<!DOCTYPE html>

<html>
<head>
  <title>nodes.coffee</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
      <ul id="jump_to">
        <li>
          <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
          <a class="small" href="javascript:void(0);">+</a>
          <div id="jump_wrapper">
          <div id="jump_page_wrapper">
            <div id="jump_page">
              
                
                <a class="source" href="browser.html">
                  browser.coffee
                </a>
              
                
                <a class="source" href="cake.html">
                  cake.coffee
                </a>
              
                
                <a class="source" href="coffeescript.html">
                  coffeescript.coffee
                </a>
              
                
                <a class="source" href="command.html">
                  command.coffee
                </a>
              
                
                <a class="source" href="grammar.html">
                  grammar.coffee
                </a>
              
                
                <a class="source" href="helpers.html">
                  helpers.coffee
                </a>
              
                
                <a class="source" href="index.html">
                  index.coffee
                </a>
              
                
                <a class="source" href="lexer.html">
                  lexer.coffee
                </a>
              
                
                <a class="source" href="nodes.html">
                  nodes.coffee
                </a>
              
                
                <a class="source" href="optparse.html">
                  optparse.coffee
                </a>
              
                
                <a class="source" href="register.html">
                  register.coffee
                </a>
              
                
                <a class="source" href="repl.html">
                  repl.coffee
                </a>
              
                
                <a class="source" href="rewriter.html">
                  rewriter.coffee
                </a>
              
                
                <a class="source" href="scope.html">
                  scope.litcoffee
                </a>
              
                
                <a class="source" href="sourcemap.html">
                  sourcemap.litcoffee
                </a>
              
            </div>
          </div>
        </li>
      </ul>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>nodes.coffee</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-1">&#x00a7;</a>
              </div>
              <p><code>nodes.coffee</code> contains all of the node classes for the syntax tree. Most
nodes are created as the result of actions in the <a href="grammar.html">grammar</a>,
but some are created by other nodes as a method of code generation. To convert
the syntax tree into a string of JavaScript code, call <code>compile()</code> on the root.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-built_in">Error</span>.stackTraceLimit = <span class="hljs-literal">Infinity</span>

{Scope} = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;./scope&#x27;</span>
{isUnassignable, JS_FORBIDDEN} = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;./lexer&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-2">&#x00a7;</a>
              </div>
              <p>Import the helpers we plan to use.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>{compact, flatten, extend, merge, del, starts, ends, some,
addDataToNode, attachCommentsToNode, locationDataToString,
throwSyntaxError, replaceUnicodeCodePointEscapes,
isFunction, isPlainObject, isNumber, parseNumber} = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;./helpers&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-3">&#x00a7;</a>
              </div>
              <p>Functions required by parser.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.extend = extend
<span class="hljs-built_in">exports</span>.addDataToNode = addDataToNode</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-4">&#x00a7;</a>
              </div>
              <p>Constant functions for nodes that don’t need customization.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">YES</span>     = -&gt;</span> <span class="hljs-literal">yes</span>
<span class="hljs-function"><span class="hljs-title">NO</span>      = -&gt;</span> <span class="hljs-literal">no</span>
<span class="hljs-function"><span class="hljs-title">THIS</span>    = -&gt;</span> this
<span class="hljs-function"><span class="hljs-title">NEGATE</span>  = -&gt;</span> @negated = <span class="hljs-keyword">not</span> @negated; this</pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-5">&#x00a7;</a>
              </div>
              <h3 id="codefragment">CodeFragment</h3>

            </div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-6">&#x00a7;</a>
              </div>
              <p>The various nodes defined below all compile to a collection of <strong>CodeFragment</strong> objects.
A CodeFragments is a block of generated code, and the location in the source file where the code
came from. CodeFragments can be assembled together into working code just by catting together
all the CodeFragments’ <code>code</code> snippets, in order.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.CodeFragment = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CodeFragment</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(parent, code)</span> -&gt;</span>
    @code = <span class="hljs-string">&quot;<span class="hljs-subst">#{code}</span>&quot;</span>
    @type = parent?.constructor?.name <span class="hljs-keyword">or</span> <span class="hljs-string">&#x27;unknown&#x27;</span>
    @locationData = parent?.locationData
    @comments = parent?.comments

  toString: <span class="hljs-function">-&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-7">&#x00a7;</a>
              </div>
              <p>This is only intended for debugging.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-string">&quot;<span class="hljs-subst">#{@code}</span><span class="hljs-subst">#{<span class="hljs-keyword">if</span> @locationData <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;: &quot;</span> + locationDataToString(@locationData) <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>}</span>&quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-8">&#x00a7;</a>
              </div>
              <p>Convert an array of CodeFragments into a string.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">fragmentsToText</span> = <span class="hljs-params">(fragments)</span> -&gt;</span>
  (fragment.code <span class="hljs-keyword">for</span> fragment <span class="hljs-keyword">in</span> fragments).join(<span class="hljs-string">&#x27;&#x27;</span>)</pre></div></div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-9">&#x00a7;</a>
              </div>
              <h3 id="base">Base</h3>

            </div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-10">&#x00a7;</a>
              </div>
              <p>The <strong>Base</strong> is the abstract base class for all nodes in the syntax tree.
Each subclass implements the <code>compileNode</code> method, which performs the
code generation for that node. To compile a node to JavaScript,
call <code>compile</code> on it, which wraps <code>compileNode</code> in some generic extra smarts,
to know when the generated code needs to be wrapped up in a closure.
An options hash is passed and cloned throughout, containing information about
the environment from higher in the tree (such as if a returned value is
being requested by the surrounding function), information about the current
scope, and indentation level.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Base = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Base</span></span>

  compile: <span class="hljs-function"><span class="hljs-params">(o, lvl)</span> -&gt;</span>
    fragmentsToText @compileToFragments o, lvl</pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-11">&#x00a7;</a>
              </div>
              <p>Occasionally a node is compiled multiple times, for example to get the name
of a variable to add to scope tracking. When we know that a “premature”
compilation won’t result in comments being output, set those comments aside
so that they’re preserved for a later <code>compile</code> call that will result in
the comments being included in the output.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileWithoutComments: <span class="hljs-function"><span class="hljs-params">(o, lvl, method = <span class="hljs-string">&#x27;compile&#x27;</span>)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @comments
      @ignoreTheseCommentsTemporarily = @comments
      <span class="hljs-keyword">delete</span> @comments
    unwrapped = @unwrapAll()
    <span class="hljs-keyword">if</span> unwrapped.comments
      unwrapped.ignoreTheseCommentsTemporarily = unwrapped.comments
      <span class="hljs-keyword">delete</span> unwrapped.comments

    fragments = @[method] o, lvl

    <span class="hljs-keyword">if</span> @ignoreTheseCommentsTemporarily
      @comments = @ignoreTheseCommentsTemporarily
      <span class="hljs-keyword">delete</span> @ignoreTheseCommentsTemporarily
    <span class="hljs-keyword">if</span> unwrapped.ignoreTheseCommentsTemporarily
      unwrapped.comments = unwrapped.ignoreTheseCommentsTemporarily
      <span class="hljs-keyword">delete</span> unwrapped.ignoreTheseCommentsTemporarily

    fragments

  compileNodeWithoutComments: <span class="hljs-function"><span class="hljs-params">(o, lvl)</span> -&gt;</span>
    @compileWithoutComments o, lvl, <span class="hljs-string">&#x27;compileNode&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-12">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-12">&#x00a7;</a>
              </div>
              <p>Common logic for determining whether to wrap this node in a closure before
compiling it, or to compile directly. We need to wrap if this node is a
<em>statement</em>, and it’s not a <em>pureStatement</em>, and we’re not at
the top level of a block (which would be unnecessary), and we haven’t
already been asked to return the result (because statements know how to
return results).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileToFragments: <span class="hljs-function"><span class="hljs-params">(o, lvl)</span> -&gt;</span>
    o        = extend {}, o
    o.level  = lvl <span class="hljs-keyword">if</span> lvl
    node     = @unfoldSoak(o) <span class="hljs-keyword">or</span> this
    node.tab = o.indent

    fragments = <span class="hljs-keyword">if</span> o.level <span class="hljs-keyword">is</span> LEVEL_TOP <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> node.isStatement(o)
      node.compileNode o
    <span class="hljs-keyword">else</span>
      node.compileClosure o
    @compileCommentFragments o, node, fragments
    fragments

  compileToFragmentsWithoutComments: <span class="hljs-function"><span class="hljs-params">(o, lvl)</span> -&gt;</span>
    @compileWithoutComments o, lvl, <span class="hljs-string">&#x27;compileToFragments&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-13">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-13">&#x00a7;</a>
              </div>
              <p>Statements converted into expressions via closure-wrapping share a scope
object with their parent closure, to preserve the expected lexical scope.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileClosure: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkForPureStatementInExpression()
    o.sharedScope = <span class="hljs-literal">yes</span>
    func = <span class="hljs-keyword">new</span> Code [], Block.wrap [this]
    args = []
    <span class="hljs-keyword">if</span> @contains (<span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span> node <span class="hljs-keyword">instanceof</span> SuperCall)
      func.bound = <span class="hljs-literal">yes</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (argumentsNode = @contains isLiteralArguments) <span class="hljs-keyword">or</span> @contains isLiteralThis
      args = [<span class="hljs-keyword">new</span> ThisLiteral]
      <span class="hljs-keyword">if</span> argumentsNode
        meth = <span class="hljs-string">&#x27;apply&#x27;</span>
        args.push <span class="hljs-keyword">new</span> IdentifierLiteral <span class="hljs-string">&#x27;arguments&#x27;</span>
      <span class="hljs-keyword">else</span>
        meth = <span class="hljs-string">&#x27;call&#x27;</span>
      func = <span class="hljs-keyword">new</span> Value func, [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> PropertyName meth]
    parts = (<span class="hljs-keyword">new</span> Call func, args).compileNode o

    <span class="hljs-keyword">switch</span>
      <span class="hljs-keyword">when</span> func.isGenerator <span class="hljs-keyword">or</span> func.base?.isGenerator
        parts.unshift @makeCode <span class="hljs-string">&quot;(yield* &quot;</span>
        parts.push    @makeCode <span class="hljs-string">&quot;)&quot;</span>
      <span class="hljs-keyword">when</span> func.isAsync <span class="hljs-keyword">or</span> func.base?.isAsync
        parts.unshift @makeCode <span class="hljs-string">&quot;(await &quot;</span>
        parts.push    @makeCode <span class="hljs-string">&quot;)&quot;</span>
    parts

  compileCommentFragments: <span class="hljs-function"><span class="hljs-params">(o, node, fragments)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> fragments <span class="hljs-keyword">unless</span> node.comments</pre></div></div>
            
        </li>
        
        
        <li id="section-14">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-14">&#x00a7;</a>
              </div>
              <p>This is where comments, that are attached to nodes as a <code>comments</code>
property, become <code>CodeFragment</code>s. “Inline block comments,” e.g.
<code>/* */</code>-delimited comments that are interspersed within code on a line,
are added to the current <code>fragments</code> stream. All other fragments are
attached as properties to the nearest preceding or following fragment,
to remain stowaways until they get properly output in <code>compileComments</code>
later on.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function">    <span class="hljs-title">unshiftCommentFragment</span> = <span class="hljs-params">(commentFragment)</span> -&gt;</span>
      <span class="hljs-keyword">if</span> commentFragment.unshift</pre></div></div>
            
        </li>
        
        
        <li id="section-15">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-15">&#x00a7;</a>
              </div>
              <p>Find the first non-comment fragment and insert <code>commentFragment</code>
before it.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        unshiftAfterComments fragments, commentFragment
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> fragments.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
          precedingFragment = fragments[fragments.length - <span class="hljs-number">1</span>]
          <span class="hljs-keyword">if</span> commentFragment.newLine <span class="hljs-keyword">and</span> precedingFragment.code <span class="hljs-keyword">isnt</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">and</span>
             <span class="hljs-keyword">not</span> <span class="hljs-regexp">/\n\s*$/</span>.test precedingFragment.code
            commentFragment.code = <span class="hljs-string">&quot;\n<span class="hljs-subst">#{commentFragment.code}</span>&quot;</span>
        fragments.push commentFragment

    <span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> node.comments <span class="hljs-keyword">when</span> comment <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> @compiledComments
      @compiledComments.push comment <span class="hljs-comment"># Don’t output this comment twice.</span></pre></div></div>
            
        </li>
        
        
        <li id="section-16">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-16">&#x00a7;</a>
              </div>
              <p>For block/here comments, denoted by <code>###</code>, that are inline comments
like <code>1 + ### comment ### 2</code>, create fragments and insert them into
the fragments array.
Otherwise attach comment fragments to their closest fragment for now,
so they can be inserted into the output later after all the newlines
have been added.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> comment.here <span class="hljs-comment"># Block comment, delimited by `###`.</span>
        commentFragment = <span class="hljs-keyword">new</span> HereComment(comment).compileNode o
      <span class="hljs-keyword">else</span> <span class="hljs-comment"># Line comment, delimited by `#`.</span>
        commentFragment = <span class="hljs-keyword">new</span> LineComment(comment).compileNode o
      <span class="hljs-keyword">if</span> (commentFragment.isHereComment <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> commentFragment.newLine) <span class="hljs-keyword">or</span>
         node.includeCommentFragments()</pre></div></div>
            
        </li>
        
        
        <li id="section-17">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-17">&#x00a7;</a>
              </div>
              <p>Inline block comments, like <code>1 + /* comment */ 2</code>, or a node whose
<code>compileToFragments</code> method has logic for outputting comments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        unshiftCommentFragment commentFragment
      <span class="hljs-keyword">else</span>
        fragments.push @makeCode <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">if</span> fragments.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
        <span class="hljs-keyword">if</span> commentFragment.unshift
          fragments[<span class="hljs-number">0</span>].precedingComments ?= []
          fragments[<span class="hljs-number">0</span>].precedingComments.push commentFragment
        <span class="hljs-keyword">else</span>
          fragments[fragments.length - <span class="hljs-number">1</span>].followingComments ?= []
          fragments[fragments.length - <span class="hljs-number">1</span>].followingComments.push commentFragment
    fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-18">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-18">&#x00a7;</a>
              </div>
              <p>If the code generation wishes to use the result of a complex expression
in multiple places, ensure that the expression is only ever evaluated once,
by assigning it to a temporary variable. Pass a level to precompile.</p>
<p>If <code>level</code> is passed, then returns <code>[val, ref]</code>, where <code>val</code> is the compiled value, and <code>ref</code>
is the compiled reference. If <code>level</code> is not passed, this returns <code>[val, ref]</code> where
the two values are raw nodes which have not been compiled.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  cache: <span class="hljs-function"><span class="hljs-params">(o, level, shouldCache)</span> -&gt;</span>
    complex = <span class="hljs-keyword">if</span> shouldCache? <span class="hljs-keyword">then</span> shouldCache this <span class="hljs-keyword">else</span> @shouldCache()
    <span class="hljs-keyword">if</span> complex
      ref = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;ref&#x27;</span>
      sub = <span class="hljs-keyword">new</span> Assign ref, this
      <span class="hljs-keyword">if</span> level <span class="hljs-keyword">then</span> [sub.compileToFragments(o, level), [@makeCode(ref.value)]] <span class="hljs-keyword">else</span> [sub, ref]
    <span class="hljs-keyword">else</span>
      ref = <span class="hljs-keyword">if</span> level <span class="hljs-keyword">then</span> @compileToFragments o, level <span class="hljs-keyword">else</span> this
      [ref, ref]</pre></div></div>
            
        </li>
        
        
        <li id="section-19">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-19">&#x00a7;</a>
              </div>
              <p>Occasionally it may be useful to make an expression behave as if it was ‘hoisted’, whereby the
result of the expression is available before its location in the source, but the expression’s
variable scope corresponds to the source position. This is used extensively to deal with executable
class bodies in classes.</p>
<p>Calling this method mutates the node, proxying the <code>compileNode</code> and <code>compileToFragments</code>
methods to store their result for later replacing the <code>target</code> node, which is returned by the
call.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  hoist: <span class="hljs-function">-&gt;</span>
    @hoisted = <span class="hljs-literal">yes</span>
    target   = <span class="hljs-keyword">new</span> HoistTarget @

    compileNode        = @compileNode
    compileToFragments = @compileToFragments

    @compileNode = <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
      target.update compileNode, o

    @compileToFragments = <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
      target.update compileToFragments, o

    target

  cacheToCodeFragments: <span class="hljs-function"><span class="hljs-params">(cacheValues)</span> -&gt;</span>
    [fragmentsToText(cacheValues[<span class="hljs-number">0</span>]), fragmentsToText(cacheValues[<span class="hljs-number">1</span>])]</pre></div></div>
            
        </li>
        
        
        <li id="section-20">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-20">&#x00a7;</a>
              </div>
              <p>Construct a node that returns the current node’s result.
Note that this is overridden for smarter behavior for
many statement nodes (e.g. <code>If</code>, <code>For</code>).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  makeReturn: <span class="hljs-function"><span class="hljs-params">(results, mark)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> mark</pre></div></div>
            
        </li>
        
        
        <li id="section-21">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-21">&#x00a7;</a>
              </div>
              <p>Mark this node as implicitly returned, so that it can be part of the
node metadata returned in the AST.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      @canBeReturned = <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">return</span>
    node = @unwrapAll()
    <span class="hljs-keyword">if</span> results
      <span class="hljs-keyword">new</span> Call <span class="hljs-keyword">new</span> Literal(<span class="hljs-string">&quot;<span class="hljs-subst">#{results}</span>.push&quot;</span>), [node]
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">new</span> Return node</pre></div></div>
            
        </li>
        
        
        <li id="section-22">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-22">&#x00a7;</a>
              </div>
              <p>Does this node, or any of its children, contain a node of a certain kind?
Recursively traverses down the <em>children</em> nodes and returns the first one
that verifies <code>pred</code>. Otherwise return undefined. <code>contains</code> does not cross
scope boundaries.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  contains: <span class="hljs-function"><span class="hljs-params">(pred)</span> -&gt;</span>
    node = <span class="hljs-literal">undefined</span>
    @traverseChildren <span class="hljs-literal">no</span>, <span class="hljs-function"><span class="hljs-params">(n)</span> -&gt;</span>
      <span class="hljs-keyword">if</span> pred n
        node = n
        <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span>
    node</pre></div></div>
            
        </li>
        
        
        <li id="section-23">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-23">&#x00a7;</a>
              </div>
              <p>Pull out the last node of a node list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  lastNode: <span class="hljs-function"><span class="hljs-params">(list)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> list.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> <span class="hljs-literal">null</span> <span class="hljs-keyword">else</span> list[list.length - <span class="hljs-number">1</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-24">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-24">&#x00a7;</a>
              </div>
              <p>Debugging representation of the node, for inspecting the parse tree.
This is what <code>coffee --nodes</code> prints out.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  toString: <span class="hljs-function"><span class="hljs-params">(idt = <span class="hljs-string">&#x27;&#x27;</span>, name = @constructor.name)</span> -&gt;</span>
    tree = <span class="hljs-string">&#x27;\n&#x27;</span> + idt + name
    tree += <span class="hljs-string">&#x27;?&#x27;</span> <span class="hljs-keyword">if</span> @soak
    @eachChild (node) -&gt; tree += node.toString idt + TAB
    tree

  checkForPureStatementInExpression: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> jumpNode = @jumps()
      jumpNode.error <span class="hljs-string">&#x27;cannot use a pure statement in an expression&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-25">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-25">&#x00a7;</a>
              </div>
              <p>Plain JavaScript object representation of the node, that can be serialized
as JSON. This is what the <code>ast</code> option in the Node API returns.
We try to follow the <a href="https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md">Babel AST spec</a>
as closely as possible, for improved interoperability with other tools.
<strong>WARNING: DO NOT OVERRIDE THIS METHOD IN CHILD CLASSES.</strong>
Only override the component <code>ast*</code> methods as needed.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  ast: <span class="hljs-function"><span class="hljs-params">(o, level)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-26">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-26">&#x00a7;</a>
              </div>
              <p>Merge <code>level</code> into <code>o</code> and perform other universal checks.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    o = @astInitialize o, level</pre></div></div>
            
        </li>
        
        
        <li id="section-27">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-27">&#x00a7;</a>
              </div>
              <p>Create serializable representation of this node.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    astNode = @astNode o</pre></div></div>
            
        </li>
        
        
        <li id="section-28">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-28">&#x00a7;</a>
              </div>
              <p>Mark AST nodes that correspond to expressions that (implicitly) return.
We can’t do this as part of <code>astNode</code> because we need to assemble child
nodes first before marking the parent being returned.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @astNode? <span class="hljs-keyword">and</span> @canBeReturned
      <span class="hljs-built_in">Object</span>.assign astNode, {returns: <span class="hljs-literal">yes</span>}
    astNode

  astInitialize: <span class="hljs-function"><span class="hljs-params">(o, level)</span> -&gt;</span>
    o = <span class="hljs-built_in">Object</span>.assign {}, o
    o.level = level <span class="hljs-keyword">if</span> level?
    <span class="hljs-keyword">if</span> o.level &gt; LEVEL_TOP
      @checkForPureStatementInExpression()</pre></div></div>
            
        </li>
        
        
        <li id="section-29">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-29">&#x00a7;</a>
              </div>
              <p><code>@makeReturn</code> must be called before <code>astProperties</code>, because the latter may call
<code>.ast()</code> for child nodes and those nodes would need the return logic from <code>makeReturn</code>
already executed by then.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @makeReturn <span class="hljs-literal">null</span>, <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @isStatement(o) <span class="hljs-keyword">and</span> o.level <span class="hljs-keyword">isnt</span> LEVEL_TOP <span class="hljs-keyword">and</span> o.scope?
    o

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-30">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-30">&#x00a7;</a>
              </div>
              <p>Every abstract syntax tree node object has four categories of properties:</p>
<ul>
<li>type, stored in the <code>type</code> field and a string like <code>NumberLiteral</code>.</li>
<li>location data, stored in the <code>loc</code>, <code>start</code>, <code>end</code> and <code>range</code> fields.</li>
<li>properties specific to this node, like <code>parsedValue</code>.</li>
<li>properties that are themselves child nodes, like <code>body</code>.
These fields are all intermixed in the Babel spec; <code>type</code> and <code>start</code> and
<code>parsedValue</code> are all top level fields in the AST node object. We have
separate methods for returning each category, that we merge together here.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-built_in">Object</span>.assign {}, {type: @astType(o)}, @astProperties(o), @astLocationData()</pre></div></div>
            
        </li>
        
        
        <li id="section-31">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-31">&#x00a7;</a>
              </div>
              <p>By default, a node class has no specific properties.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  astProperties: <span class="hljs-function">-&gt;</span> {}</pre></div></div>
            
        </li>
        
        
        <li id="section-32">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-32">&#x00a7;</a>
              </div>
              <p>By default, a node class’s AST <code>type</code> is its class name.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  astType: <span class="hljs-function">-&gt;</span> @constructor.name</pre></div></div>
            
        </li>
        
        
        <li id="section-33">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-33">&#x00a7;</a>
              </div>
              <p>The AST location data is a rearranged version of our Jison location data,
mutated into the structure that the Babel spec uses.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  astLocationData: <span class="hljs-function">-&gt;</span>
    jisonLocationDataToAstLocationData @locationData</pre></div></div>
            
        </li>
        
        
        <li id="section-34">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-34">&#x00a7;</a>
              </div>
              <p>Determines whether an AST node needs an <code>ExpressionStatement</code> wrapper.
Typically matches our <code>isStatement()</code> logic but this allows overriding.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  isStatementAst: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @isStatement o</pre></div></div>
            
        </li>
        
        
        <li id="section-35">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-35">&#x00a7;</a>
              </div>
              <p>Passes each child to a function, breaking when the function returns <code>false</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  eachChild: <span class="hljs-function"><span class="hljs-params">(func)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> this <span class="hljs-keyword">unless</span> @children
    <span class="hljs-keyword">for</span> attr <span class="hljs-keyword">in</span> @children <span class="hljs-keyword">when</span> @[attr]
      <span class="hljs-keyword">for</span> child <span class="hljs-keyword">in</span> flatten [@[attr]]
        <span class="hljs-keyword">return</span> this <span class="hljs-keyword">if</span> func(child) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>
    this

  traverseChildren: <span class="hljs-function"><span class="hljs-params">(crossScope, func)</span> -&gt;</span>
    @eachChild (child) -&gt;
      recur = func(child)
      child.traverseChildren(crossScope, func) <span class="hljs-keyword">unless</span> recur <span class="hljs-keyword">is</span> <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-36">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-36">&#x00a7;</a>
              </div>
              <p><code>replaceInContext</code> will traverse children looking for a node for which <code>match</code> returns
true. Once found, the matching node will be replaced by the result of calling <code>replacement</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  replaceInContext: <span class="hljs-function"><span class="hljs-params">(match, replacement)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> <span class="hljs-keyword">unless</span> @children
    <span class="hljs-keyword">for</span> attr <span class="hljs-keyword">in</span> @children <span class="hljs-keyword">when</span> children = @[attr]
      <span class="hljs-keyword">if</span> <span class="hljs-built_in">Array</span>.isArray children
        <span class="hljs-keyword">for</span> child, i <span class="hljs-keyword">in</span> children
          <span class="hljs-keyword">if</span> match child
            children[i..i] = replacement child, @
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
          <span class="hljs-keyword">else</span>
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">if</span> child.replaceInContext match, replacement
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> match children
        @[attr] = replacement children, @
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">if</span> children.replaceInContext match, replacement

  invert: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">new</span> Op <span class="hljs-string">&#x27;!&#x27;</span>, this

  unwrapAll: <span class="hljs-function">-&gt;</span>
    node = this
    <span class="hljs-keyword">continue</span> <span class="hljs-keyword">until</span> node <span class="hljs-keyword">is</span> node = node.unwrap()
    node</pre></div></div>
            
        </li>
        
        
        <li id="section-37">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-37">&#x00a7;</a>
              </div>
              <p>Default implementations of the common node properties and methods. Nodes
will override these with custom logic, if needed.</p>

            </div>
            
        </li>
        
        
        <li id="section-38">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-38">&#x00a7;</a>
              </div>
              <p><code>children</code> are the properties to recurse into when tree walking. The
<code>children</code> list <em>is</em> the structure of the AST. The <code>parent</code> pointer, and
the pointer to the <code>children</code> are how you can traverse the tree.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  children: []</pre></div></div>
            
        </li>
        
        
        <li id="section-39">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-39">&#x00a7;</a>
              </div>
              <p><code>isStatement</code> has to do with “everything is an expression”. A few things
can’t be expressions, such as <code>break</code>. Things that <code>isStatement</code> returns
<code>true</code> for are things that can’t be used as expressions. There are some
error messages that come from <code>nodes.coffee</code> due to statements ending up
in expression position.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  isStatement: NO</pre></div></div>
            
        </li>
        
        
        <li id="section-40">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-40">&#x00a7;</a>
              </div>
              <p>Track comments that have been compiled into fragments, to avoid outputting
them twice.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compiledComments: []</pre></div></div>
            
        </li>
        
        
        <li id="section-41">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-41">&#x00a7;</a>
              </div>
              <p><code>includeCommentFragments</code> lets <code>compileCommentFragments</code> know whether this node
has special awareness of how to handle comments within its output.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  includeCommentFragments: NO</pre></div></div>
            
        </li>
        
        
        <li id="section-42">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-42">&#x00a7;</a>
              </div>
              <p><code>jumps</code> tells you if an expression, or an internal part of an expression,
has a flow control construct (like <code>break</code>, <code>continue</code>, or <code>return</code>)
that jumps out of the normal flow of control and can’t be used as a value.
(Note that <code>throw</code> is not considered a flow control construct.)
This is important because flow control in the middle of an expression
makes no sense; we have to disallow it.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  jumps: NO</pre></div></div>
            
        </li>
        
        
        <li id="section-43">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-43">&#x00a7;</a>
              </div>
              <p>If <code>node.shouldCache() is false</code>, it is safe to use <code>node</code> more than once.
Otherwise you need to store the value of <code>node</code> in a variable and output
that variable several times instead. Kind of like this: <code>5</code> need not be
cached. <code>returnFive()</code>, however, could have side effects as a result of
evaluating it more than once, and therefore we need to cache it. The
parameter is named <code>shouldCache</code> rather than <code>mustCache</code> because there are
also cases where we might not need to cache but where we want to, for
example a long expression that may well be idempotent but we want to cache
for brevity.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  shouldCache: YES

  isChainable: NO
  isAssignable: NO
  isNumber: NO

  unwrap: THIS
  unfoldSoak: NO</pre></div></div>
            
        </li>
        
        
        <li id="section-44">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-44">&#x00a7;</a>
              </div>
              <p>Is this node used to assign a certain variable?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  assigns: NO</pre></div></div>
            
        </li>
        
        
        <li id="section-45">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-45">&#x00a7;</a>
              </div>
              <p>For this node and all descendents, set the location data to <code>locationData</code>
if the location data is not already set.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  updateLocationDataIfMissing: <span class="hljs-function"><span class="hljs-params">(locationData, force)</span> -&gt;</span>
    @forceUpdateLocation = <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> force
    <span class="hljs-keyword">return</span> this <span class="hljs-keyword">if</span> @locationData <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @forceUpdateLocation
    <span class="hljs-keyword">delete</span> @forceUpdateLocation
    @locationData = locationData

    @eachChild (child) -&gt;
      child.updateLocationDataIfMissing locationData</pre></div></div>
            
        </li>
        
        
        <li id="section-46">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-46">&#x00a7;</a>
              </div>
              <p>Add location data from another node</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  withLocationDataFrom: <span class="hljs-function"><span class="hljs-params">({locationData})</span> -&gt;</span>
    @updateLocationDataIfMissing locationData</pre></div></div>
            
        </li>
        
        
        <li id="section-47">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-47">&#x00a7;</a>
              </div>
              <p>Add location data and comments from another node</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  withLocationDataAndCommentsFrom: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    @withLocationDataFrom node
    {comments} = node
    @comments = comments <span class="hljs-keyword">if</span> comments?.length
    this</pre></div></div>
            
        </li>
        
        
        <li id="section-48">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-48">&#x00a7;</a>
              </div>
              <p>Throw a SyntaxError associated with this node’s location.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  error: <span class="hljs-function"><span class="hljs-params">(message)</span> -&gt;</span>
    throwSyntaxError message, @locationData

  makeCode: <span class="hljs-function"><span class="hljs-params">(code)</span> -&gt;</span>
    <span class="hljs-keyword">new</span> CodeFragment this, code

  wrapInParentheses: <span class="hljs-function"><span class="hljs-params">(fragments)</span> -&gt;</span>
    [@makeCode(<span class="hljs-string">&#x27;(&#x27;</span>), fragments..., @makeCode(<span class="hljs-string">&#x27;)&#x27;</span>)]

  wrapInBraces: <span class="hljs-function"><span class="hljs-params">(fragments)</span> -&gt;</span>
    [@makeCode(<span class="hljs-string">&#x27;{&#x27;</span>), fragments..., @makeCode(<span class="hljs-string">&#x27;}&#x27;</span>)]</pre></div></div>
            
        </li>
        
        
        <li id="section-49">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-49">&#x00a7;</a>
              </div>
              <p><code>fragmentsList</code> is an array of arrays of fragments. Each array in fragmentsList will be
concatenated together, with <code>joinStr</code> added in between each, to produce a final flat array
of fragments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  joinFragmentArrays: <span class="hljs-function"><span class="hljs-params">(fragmentsList, joinStr)</span> -&gt;</span>
    answer = []
    <span class="hljs-keyword">for</span> fragments, i <span class="hljs-keyword">in</span> fragmentsList
      <span class="hljs-keyword">if</span> i <span class="hljs-keyword">then</span> answer.push @makeCode joinStr
      answer = answer.concat fragments
    answer</pre></div></div>
            
        </li>
        
        
        <li id="section-50">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-50">&#x00a7;</a>
              </div>
              <h3 id="hoisttarget">HoistTarget</h3>

            </div>
            
        </li>
        
        
        <li id="section-51">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-51">&#x00a7;</a>
              </div>
              <p>A <strong>HoistTargetNode</strong> represents the output location in the node tree for a hoisted node.
See Base#hoist.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.HoistTarget = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HoistTarget</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span></pre></div></div>
            
        </li>
        
        
        <li id="section-52">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-52">&#x00a7;</a>
              </div>
              <p>Expands hoisted fragments in the given array</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  @expand = <span class="hljs-function"><span class="hljs-params">(fragments)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> fragment, i <span class="hljs-keyword">in</span> fragments <span class="hljs-keyword">by</span> <span class="hljs-number">-1</span> <span class="hljs-keyword">when</span> fragment.fragments
      fragments[i..i] = @expand fragment.fragments
    fragments

  constructor: <span class="hljs-function"><span class="hljs-params">(@source)</span> -&gt;</span>
    super()</pre></div></div>
            
        </li>
        
        
        <li id="section-53">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-53">&#x00a7;</a>
              </div>
              <p>Holds presentational options to apply when the source node is compiled.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @options = {}</pre></div></div>
            
        </li>
        
        
        <li id="section-54">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-54">&#x00a7;</a>
              </div>
              <p>Placeholder fragments to be replaced by the source node’s compilation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @targetFragments = { fragments: [] }

  isStatement: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @source.isStatement o</pre></div></div>
            
        </li>
        
        
        <li id="section-55">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-55">&#x00a7;</a>
              </div>
              <p>Update the target fragments with the result of compiling the source.
Calls the given compile function with the node and options (overriden with the target
presentational options).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  update: <span class="hljs-function"><span class="hljs-params">(compile, o)</span> -&gt;</span>
    @targetFragments.fragments = compile.call @source, merge o, @options</pre></div></div>
            
        </li>
        
        
        <li id="section-56">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-56">&#x00a7;</a>
              </div>
              <p>Copies the target indent and level, and returns the placeholder fragments</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileToFragments: <span class="hljs-function"><span class="hljs-params">(o, level)</span> -&gt;</span>
    @options.indent = o.indent
    @options.level  = level ? o.level
    [ @targetFragments ]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @compileToFragments o

  compileClosure: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-57">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-57">&#x00a7;</a>
              </div>
              <h3 id="root">Root</h3>

            </div>
            
        </li>
        
        
        <li id="section-58">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-58">&#x00a7;</a>
              </div>
              <p>The root node of the node tree</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Root = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Root</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@body)</span> -&gt;</span>
    super()

    @isAsync = (<span class="hljs-keyword">new</span> Code [], @body).isAsync

  children: [<span class="hljs-string">&#x27;body&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-59">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-59">&#x00a7;</a>
              </div>
              <p>Wrap everything in a safety closure, unless requested not to. It would be
better not to generate them in the first place, but for now, clean up
obvious double-parentheses.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.indent    = <span class="hljs-keyword">if</span> o.bare <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">else</span> TAB
    o.level     = LEVEL_TOP
    o.compiling = <span class="hljs-literal">yes</span>
    @initializeScope o
    fragments = @body.compileRoot o
    <span class="hljs-keyword">return</span> fragments <span class="hljs-keyword">if</span> o.bare
    functionKeyword = <span class="hljs-string">&quot;<span class="hljs-subst">#{<span class="hljs-keyword">if</span> @isAsync <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;async &#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>}</span>function&quot;</span>
    [].concat @makeCode(<span class="hljs-string">&quot;(<span class="hljs-subst">#{functionKeyword}</span>() {\n&quot;</span>), fragments, @makeCode(<span class="hljs-string">&quot;\n}).call(this);\n&quot;</span>)

  initializeScope: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.scope = <span class="hljs-keyword">new</span> Scope <span class="hljs-literal">null</span>, @body, <span class="hljs-literal">null</span>, o.referencedVars ? []</pre></div></div>
            
        </li>
        
        
        <li id="section-60">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-60">&#x00a7;</a>
              </div>
              <p>Mark given local variables in the root scope as parameters so they don’t
end up being declared on the root block.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    o.scope.parameter name <span class="hljs-keyword">for</span> name <span class="hljs-keyword">in</span> o.locals <span class="hljs-keyword">or</span> []

  commentsAst: <span class="hljs-function">-&gt;</span>
    @allComments ?=
      <span class="hljs-keyword">for</span> commentToken <span class="hljs-keyword">in</span> (@allCommentTokens ? []) <span class="hljs-keyword">when</span> <span class="hljs-keyword">not</span> commentToken.heregex
        <span class="hljs-keyword">if</span> commentToken.here
          <span class="hljs-keyword">new</span> HereComment commentToken
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">new</span> LineComment commentToken
    comment.ast() <span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> @allComments

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.level = LEVEL_TOP
    @initializeScope o
    super o

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;File&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @body.isRootBlock = <span class="hljs-literal">yes</span>
    <span class="hljs-keyword">return</span>
      program: <span class="hljs-built_in">Object</span>.assign @body.ast(o), @astLocationData()
      comments: @commentsAst()</pre></div></div>
            
        </li>
        
        
        <li id="section-61">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-61">&#x00a7;</a>
              </div>
              <h3 id="block">Block</h3>

            </div>
            
        </li>
        
        
        <li id="section-62">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-62">&#x00a7;</a>
              </div>
              <p>The block is the list of expressions that forms the body of an
indented block of code – the implementation of a function, a clause in an
<code>if</code>, <code>switch</code>, or <code>try</code>, and so on…</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Block = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Block</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(nodes)</span> -&gt;</span>
    super()

    @expressions = compact flatten nodes <span class="hljs-keyword">or</span> []

  children: [<span class="hljs-string">&#x27;expressions&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-63">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-63">&#x00a7;</a>
              </div>
              <p>Tack an expression on to the end of this expression list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  push: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    @expressions.push node
    this</pre></div></div>
            
        </li>
        
        
        <li id="section-64">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-64">&#x00a7;</a>
              </div>
              <p>Remove and return the last expression of this expression list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  pop: <span class="hljs-function">-&gt;</span>
    @expressions.pop()</pre></div></div>
            
        </li>
        
        
        <li id="section-65">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-65">&#x00a7;</a>
              </div>
              <p>Add an expression at the beginning of this expression list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  unshift: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    @expressions.unshift node
    this</pre></div></div>
            
        </li>
        
        
        <li id="section-66">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-66">&#x00a7;</a>
              </div>
              <p>If this Block consists of just a single node, unwrap it by pulling
it back out.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  unwrap: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @expressions.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">then</span> @expressions[<span class="hljs-number">0</span>] <span class="hljs-keyword">else</span> this</pre></div></div>
            
        </li>
        
        
        <li id="section-67">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-67">&#x00a7;</a>
              </div>
              <p>Is this an empty block of code?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  isEmpty: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">not</span> @expressions.length

  isStatement: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> exp <span class="hljs-keyword">in</span> @expressions <span class="hljs-keyword">when</span> exp.isStatement o
      <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>
    <span class="hljs-literal">no</span>

  jumps: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> exp <span class="hljs-keyword">in</span> @expressions
      <span class="hljs-keyword">return</span> jumpNode <span class="hljs-keyword">if</span> jumpNode = exp.jumps o</pre></div></div>
            
        </li>
        
        
        <li id="section-68">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-68">&#x00a7;</a>
              </div>
              <p>A Block node does not return its entire body, rather it
ensures that the final expression is returned.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  makeReturn: <span class="hljs-function"><span class="hljs-params">(results, mark)</span> -&gt;</span>
    len = @expressions.length
    [..., lastExp] = @expressions
    lastExp = lastExp?.unwrap() <span class="hljs-keyword">or</span> <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-69">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-69">&#x00a7;</a>
              </div>
              <p>We also need to check that we’re not returning a JSX tag if there’s an
adjacent one at the same level; JSX doesn’t allow that.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> lastExp <span class="hljs-keyword">and</span> lastExp <span class="hljs-keyword">instanceof</span> Parens <span class="hljs-keyword">and</span> lastExp.body.expressions.length &gt; <span class="hljs-number">1</span>
      {body:{expressions}} = lastExp
      [..., penult, last] = expressions
      penult = penult.unwrap()
      last = last.unwrap()
      <span class="hljs-keyword">if</span> penult <span class="hljs-keyword">instanceof</span> JSXElement <span class="hljs-keyword">and</span> last <span class="hljs-keyword">instanceof</span> JSXElement
        expressions[expressions.length - <span class="hljs-number">1</span>].error <span class="hljs-string">&#x27;Adjacent JSX elements must be wrapped in an enclosing tag&#x27;</span>
    <span class="hljs-keyword">if</span> mark
      @expressions[len - <span class="hljs-number">1</span>]?.makeReturn results, mark
      <span class="hljs-keyword">return</span>
    <span class="hljs-keyword">while</span> len--
      expr = @expressions[len]
      @expressions[len] = expr.makeReturn results
      @expressions.splice(len, <span class="hljs-number">1</span>) <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">instanceof</span> Return <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> expr.expression
      <span class="hljs-keyword">break</span>
    this

  compile: <span class="hljs-function"><span class="hljs-params">(o, lvl)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Root(this).withLocationDataFrom(this).compile o, lvl <span class="hljs-keyword">unless</span> o.scope

    super o, lvl</pre></div></div>
            
        </li>
        
        
        <li id="section-70">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-70">&#x00a7;</a>
              </div>
              <p>Compile all expressions within the <strong>Block</strong> body. If we need to return
the result, and it’s an expression, simply return it. If it’s a statement,
ask the statement to do so.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @tab  = o.indent
    top   = o.level <span class="hljs-keyword">is</span> LEVEL_TOP
    compiledNodes = []

    <span class="hljs-keyword">for</span> node, index <span class="hljs-keyword">in</span> @expressions
      <span class="hljs-keyword">if</span> node.hoisted</pre></div></div>
            
        </li>
        
        
        <li id="section-71">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-71">&#x00a7;</a>
              </div>
              <p>This is a hoisted expression.
We want to compile this and ignore the result.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        node.compileToFragments o
        <span class="hljs-keyword">continue</span>
      node = (node.unfoldSoak(o) <span class="hljs-keyword">or</span> node)
      <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Block</pre></div></div>
            
        </li>
        
        
        <li id="section-72">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-72">&#x00a7;</a>
              </div>
              <p>This is a nested block. We don’t do anything special here like
enclose it in a new scope; we just compile the statements in this
block along with our own.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        compiledNodes.push node.compileNode o
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> top
        node.front = <span class="hljs-literal">yes</span>
        fragments = node.compileToFragments o
        <span class="hljs-keyword">unless</span> node.isStatement o
          fragments = indentInitial fragments, @
          [..., lastFragment] = fragments
          <span class="hljs-keyword">unless</span> lastFragment.code <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">or</span> lastFragment.isComment
            fragments.push @makeCode <span class="hljs-string">&#x27;;&#x27;</span>
        compiledNodes.push fragments
      <span class="hljs-keyword">else</span>
        compiledNodes.push node.compileToFragments o, LEVEL_LIST
    <span class="hljs-keyword">if</span> top
      <span class="hljs-keyword">if</span> @spaced
        <span class="hljs-keyword">return</span> [].concat @joinFragmentArrays(compiledNodes, <span class="hljs-string">&#x27;\n\n&#x27;</span>), @makeCode(<span class="hljs-string">&#x27;\n&#x27;</span>)
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">return</span> @joinFragmentArrays(compiledNodes, <span class="hljs-string">&#x27;\n&#x27;</span>)
    <span class="hljs-keyword">if</span> compiledNodes.length
      answer = @joinFragmentArrays(compiledNodes, <span class="hljs-string">&#x27;, &#x27;</span>)
    <span class="hljs-keyword">else</span>
      answer = [@makeCode <span class="hljs-string">&#x27;void 0&#x27;</span>]
    <span class="hljs-keyword">if</span> compiledNodes.length &gt; <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> o.level &gt;= LEVEL_LIST <span class="hljs-keyword">then</span> @wrapInParentheses answer <span class="hljs-keyword">else</span> answer

  compileRoot: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @spaced = <span class="hljs-literal">yes</span>
    fragments = @compileWithDeclarations o
    HoistTarget.expand fragments
    @compileComments fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-73">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-73">&#x00a7;</a>
              </div>
              <p>Compile the expressions body for the contents of a function, with
declarations of all inner variables pushed up to the top.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileWithDeclarations: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    fragments = []
    post = []
    <span class="hljs-keyword">for</span> exp, i <span class="hljs-keyword">in</span> @expressions
      exp = exp.unwrap()
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> exp <span class="hljs-keyword">instanceof</span> Literal
    o = merge(o, level: LEVEL_TOP)
    <span class="hljs-keyword">if</span> i
      rest = @expressions.splice i, <span class="hljs-number">9e9</span>
      [spaced,    @spaced] = [@spaced, <span class="hljs-literal">no</span>]
      [fragments, @spaced] = [@compileNode(o), spaced]
      @expressions = rest
    post = @compileNode o
    {scope} = o
    <span class="hljs-keyword">if</span> scope.expressions <span class="hljs-keyword">is</span> this
      declars = o.scope.hasDeclarations()
      assigns = scope.hasAssignments
      <span class="hljs-keyword">if</span> declars <span class="hljs-keyword">or</span> assigns
        fragments.push @makeCode <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">if</span> i
        fragments.push @makeCode <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span>var &quot;</span>
        <span class="hljs-keyword">if</span> declars
          declaredVariables = scope.declaredVariables()
          <span class="hljs-keyword">for</span> declaredVariable, declaredVariablesIndex <span class="hljs-keyword">in</span> declaredVariables
            fragments.push @makeCode declaredVariable
            <span class="hljs-keyword">if</span> Object::hasOwnProperty.call o.scope.comments, declaredVariable
              fragments.push o.scope.comments[declaredVariable]...
            <span class="hljs-keyword">if</span> declaredVariablesIndex <span class="hljs-keyword">isnt</span> declaredVariables.length - <span class="hljs-number">1</span>
              fragments.push @makeCode <span class="hljs-string">&#x27;, &#x27;</span>
        <span class="hljs-keyword">if</span> assigns
          fragments.push @makeCode <span class="hljs-string">&quot;,\n<span class="hljs-subst">#{@tab + TAB}</span>&quot;</span> <span class="hljs-keyword">if</span> declars
          fragments.push @makeCode scope.assignedVariables().join(<span class="hljs-string">&quot;,\n<span class="hljs-subst">#{@tab + TAB}</span>&quot;</span>)
        fragments.push @makeCode <span class="hljs-string">&quot;;\n<span class="hljs-subst">#{<span class="hljs-keyword">if</span> @spaced <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>}</span>&quot;</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> fragments.length <span class="hljs-keyword">and</span> post.length
        fragments.push @makeCode <span class="hljs-string">&quot;\n&quot;</span>
    fragments.concat post

  compileComments: <span class="hljs-function"><span class="hljs-params">(fragments)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> fragment, fragmentIndex <span class="hljs-keyword">in</span> fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-74">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-74">&#x00a7;</a>
              </div>
              <p>Insert comments into the output at the next or previous newline.
If there are no newlines at which to place comments, create them.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> fragment.precedingComments</pre></div></div>
            
        </li>
        
        
        <li id="section-75">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-75">&#x00a7;</a>
              </div>
              <p>Determine the indentation level of the fragment that we are about
to insert comments before, and use that indentation level for our
inserted comments. At this point, the fragments’ <code>code</code> property
is the generated output JavaScript, and CoffeeScript always
generates output indented by two spaces; so all we need to do is
search for a <code>code</code> property that begins with at least two spaces.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        fragmentIndent = <span class="hljs-string">&#x27;&#x27;</span>
        <span class="hljs-keyword">for</span> pastFragment <span class="hljs-keyword">in</span> fragments[<span class="hljs-number">0.</span>..(fragmentIndex + <span class="hljs-number">1</span>)] <span class="hljs-keyword">by</span> <span class="hljs-number">-1</span>
          indent = <span class="hljs-regexp">/^ {2,}/m</span>.exec pastFragment.code
          <span class="hljs-keyword">if</span> indent
            fragmentIndent = indent[<span class="hljs-number">0</span>]
            <span class="hljs-keyword">break</span>
          <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">in</span> pastFragment.code
            <span class="hljs-keyword">break</span>
        code = <span class="hljs-string">&quot;\n<span class="hljs-subst">#{fragmentIndent}</span>&quot;</span> + (
            <span class="hljs-keyword">for</span> commentFragment <span class="hljs-keyword">in</span> fragment.precedingComments
              <span class="hljs-keyword">if</span> commentFragment.isHereComment <span class="hljs-keyword">and</span> commentFragment.multiline
                multident commentFragment.code, fragmentIndent, <span class="hljs-literal">no</span>
              <span class="hljs-keyword">else</span>
                commentFragment.code
          ).join(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{fragmentIndent}</span>&quot;</span>).replace <span class="hljs-regexp">/^(\s*)$/gm</span>, <span class="hljs-string">&#x27;&#x27;</span>
        <span class="hljs-keyword">for</span> pastFragment, pastFragmentIndex <span class="hljs-keyword">in</span> fragments[<span class="hljs-number">0.</span>..(fragmentIndex + <span class="hljs-number">1</span>)] <span class="hljs-keyword">by</span> <span class="hljs-number">-1</span>
          newLineIndex = pastFragment.code.lastIndexOf <span class="hljs-string">&#x27;\n&#x27;</span>
          <span class="hljs-keyword">if</span> newLineIndex <span class="hljs-keyword">is</span> <span class="hljs-number">-1</span></pre></div></div>
            
        </li>
        
        
        <li id="section-76">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-76">&#x00a7;</a>
              </div>
              <p>Keep searching previous fragments until we can’t go back any
further, either because there are no fragments left or we’ve
discovered that we’re in a code block that is interpolated
inside a string.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span> pastFragmentIndex <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
              pastFragment.code = <span class="hljs-string">&#x27;\n&#x27;</span> + pastFragment.code
              newLineIndex = <span class="hljs-number">0</span>
            <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> pastFragment.isStringWithInterpolations <span class="hljs-keyword">and</span> pastFragment.code <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;{&#x27;</span>
              code = code[<span class="hljs-number">1.</span>.] + <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-comment"># Move newline to end.</span>
              newLineIndex = <span class="hljs-number">1</span>
            <span class="hljs-keyword">else</span>
              <span class="hljs-keyword">continue</span>
          <span class="hljs-keyword">delete</span> fragment.precedingComments
          pastFragment.code = pastFragment.code[<span class="hljs-number">0.</span>..newLineIndex] +
            code + pastFragment.code[newLineIndex..]
          <span class="hljs-keyword">break</span></pre></div></div>
            
        </li>
        
        
        <li id="section-77">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-77">&#x00a7;</a>
              </div>
              <p>Yes, this is awfully similar to the previous <code>if</code> block, but if you
look closely you’ll find lots of tiny differences that make this
confusing if it were abstracted into a function that both blocks share.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> fragment.followingComments</pre></div></div>
            
        </li>
        
        
        <li id="section-78">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-78">&#x00a7;</a>
              </div>
              <p>Does the first trailing comment follow at the end of a line of code,
like <code>; // Comment</code>, or does it start a new line after a line of code?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        trail = fragment.followingComments[<span class="hljs-number">0</span>].trail
        fragmentIndent = <span class="hljs-string">&#x27;&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-79">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-79">&#x00a7;</a>
              </div>
              <p>Find the indent of the next line of code, if we have any non-trailing
comments to output. We need to first find the next newline, as these
comments will be output after that; and then the indent of the line
that follows the next newline.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">unless</span> trail <span class="hljs-keyword">and</span> fragment.followingComments.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
          onNextLine = <span class="hljs-literal">no</span>
          <span class="hljs-keyword">for</span> upcomingFragment <span class="hljs-keyword">in</span> fragments[fragmentIndex...]
            <span class="hljs-keyword">unless</span> onNextLine
              <span class="hljs-keyword">if</span> <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">in</span> upcomingFragment.code
                onNextLine = <span class="hljs-literal">yes</span>
              <span class="hljs-keyword">else</span>
                <span class="hljs-keyword">continue</span>
            <span class="hljs-keyword">else</span>
              indent = <span class="hljs-regexp">/^ {2,}/m</span>.exec upcomingFragment.code
              <span class="hljs-keyword">if</span> indent
                fragmentIndent = indent[<span class="hljs-number">0</span>]
                <span class="hljs-keyword">break</span>
              <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">in</span> upcomingFragment.code
                <span class="hljs-keyword">break</span></pre></div></div>
            
        </li>
        
        
        <li id="section-80">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-80">&#x00a7;</a>
              </div>
              <p>Is this comment following the indent inserted by bare mode?
If so, there’s no need to indent this further.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        code = <span class="hljs-keyword">if</span> fragmentIndex <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> <span class="hljs-regexp">/^\s+$/</span>.test fragments[<span class="hljs-number">0</span>].code
          <span class="hljs-string">&#x27;&#x27;</span>
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> trail
          <span class="hljs-string">&#x27; &#x27;</span>
        <span class="hljs-keyword">else</span>
          <span class="hljs-string">&quot;\n<span class="hljs-subst">#{fragmentIndent}</span>&quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-81">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-81">&#x00a7;</a>
              </div>
              <p>Assemble properly indented comments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        code += (
            <span class="hljs-keyword">for</span> commentFragment <span class="hljs-keyword">in</span> fragment.followingComments
              <span class="hljs-keyword">if</span> commentFragment.isHereComment <span class="hljs-keyword">and</span> commentFragment.multiline
                multident commentFragment.code, fragmentIndent, <span class="hljs-literal">no</span>
              <span class="hljs-keyword">else</span>
                commentFragment.code
          ).join(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{fragmentIndent}</span>&quot;</span>).replace <span class="hljs-regexp">/^(\s*)$/gm</span>, <span class="hljs-string">&#x27;&#x27;</span>
        <span class="hljs-keyword">for</span> upcomingFragment, upcomingFragmentIndex <span class="hljs-keyword">in</span> fragments[fragmentIndex...]
          newLineIndex = upcomingFragment.code.indexOf <span class="hljs-string">&#x27;\n&#x27;</span>
          <span class="hljs-keyword">if</span> newLineIndex <span class="hljs-keyword">is</span> <span class="hljs-number">-1</span></pre></div></div>
            
        </li>
        
        
        <li id="section-82">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-82">&#x00a7;</a>
              </div>
              <p>Keep searching upcoming fragments until we can’t go any
further, either because there are no fragments left or we’ve
discovered that we’re in a code block that is interpolated
inside a string.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span> upcomingFragmentIndex <span class="hljs-keyword">is</span> fragments.length - <span class="hljs-number">1</span>
              upcomingFragment.code = upcomingFragment.code + <span class="hljs-string">&#x27;\n&#x27;</span>
              newLineIndex = upcomingFragment.code.length
            <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> upcomingFragment.isStringWithInterpolations <span class="hljs-keyword">and</span> upcomingFragment.code <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;}&#x27;</span>
              code = <span class="hljs-string">&quot;<span class="hljs-subst">#{code}</span>\n&quot;</span>
              newLineIndex = <span class="hljs-number">0</span>
            <span class="hljs-keyword">else</span>
              <span class="hljs-keyword">continue</span>
          <span class="hljs-keyword">delete</span> fragment.followingComments</pre></div></div>
            
        </li>
        
        
        <li id="section-83">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-83">&#x00a7;</a>
              </div>
              <p>Avoid inserting extra blank lines.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          code = code.replace <span class="hljs-regexp">/^\n/</span>, <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">if</span> upcomingFragment.code <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;\n&#x27;</span>
          upcomingFragment.code = upcomingFragment.code[<span class="hljs-number">0.</span>..newLineIndex] +
            code + upcomingFragment.code[newLineIndex..]
          <span class="hljs-keyword">break</span>

    fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-84">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-84">&#x00a7;</a>
              </div>
              <p>Wrap up the given nodes as a <strong>Block</strong>, unless it already happens
to be one.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  @wrap: <span class="hljs-function"><span class="hljs-params">(nodes)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> nodes[<span class="hljs-number">0</span>] <span class="hljs-keyword">if</span> nodes.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> nodes[<span class="hljs-number">0</span>] <span class="hljs-keyword">instanceof</span> Block
    <span class="hljs-keyword">new</span> Block nodes

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> (o.level? <span class="hljs-keyword">and</span> o.level <span class="hljs-keyword">isnt</span> LEVEL_TOP) <span class="hljs-keyword">and</span> @expressions.length
      <span class="hljs-keyword">return</span> (<span class="hljs-keyword">new</span> Sequence(@expressions).withLocationDataFrom @).ast o

    super o

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isRootBlock
      <span class="hljs-string">&#x27;Program&#x27;</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @isClassBody
      <span class="hljs-string">&#x27;ClassBody&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;BlockStatement&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    checkForDirectives = del o, <span class="hljs-string">&#x27;checkForDirectives&#x27;</span>

    sniffDirectives @expressions, notFinalExpression: checkForDirectives <span class="hljs-keyword">if</span> @isRootBlock <span class="hljs-keyword">or</span> checkForDirectives
    directives = []
    body = []
    <span class="hljs-keyword">for</span> expression <span class="hljs-keyword">in</span> @expressions
      expressionAst = expression.ast o</pre></div></div>
            
        </li>
        
        
        <li id="section-85">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-85">&#x00a7;</a>
              </div>
              <p>Ignore generated PassthroughLiteral</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> expressionAst?
        <span class="hljs-keyword">continue</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> expression <span class="hljs-keyword">instanceof</span> Directive
        directives.push expressionAst</pre></div></div>
            
        </li>
        
        
        <li id="section-86">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-86">&#x00a7;</a>
              </div>
              <p>If an expression is a statement, it can be added to the body as is.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> expression.isStatementAst o
        body.push expressionAst</pre></div></div>
            
        </li>
        
        
        <li id="section-87">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-87">&#x00a7;</a>
              </div>
              <p>Otherwise, we need to wrap it in an <code>ExpressionStatement</code> AST node.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">else</span>
        body.push <span class="hljs-built_in">Object</span>.assign
            type: <span class="hljs-string">&#x27;ExpressionStatement&#x27;</span>
            expression: expressionAst
          ,
            expression.astLocationData()

    <span class="hljs-keyword">return</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-88">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-88">&#x00a7;</a>
              </div>
              <p>For now, we’re not including <code>sourceType</code> on the <code>Program</code> AST node.
Its value could be either <code>&#39;script&#39;</code> or <code>&#39;module&#39;</code>, and there’s no way
for CoffeeScript to always know which it should be. The presence of an
<code>import</code> or <code>export</code> statement in source code would imply that it should
be a <code>module</code>, but a project may consist of mostly such files and also
an outlier file that lacks <code>import</code> or <code>export</code> but is still imported
into the project and therefore expects to be treated as a <code>module</code>.
Determining the value of <code>sourceType</code> is essentially the same challenge
posed by determining the parse goal of a JavaScript file, also <code>module</code>
or <code>script</code>, and so if Node figures out a way to do so for <code>.js</code> files
then CoffeeScript can copy Node’s algorithm.</p>

            </div>
            
        </li>
        
        
        <li id="section-89">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-89">&#x00a7;</a>
              </div>
              <p>sourceType: ‘module’</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      body, directives
    }

  astLocationData: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> @isRootBlock <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @locationData?
    super()</pre></div></div>
            
        </li>
        
        
        <li id="section-90">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-90">&#x00a7;</a>
              </div>
              <p>A directive e.g. ‘use strict’.
Currently only used during AST generation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Directive = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Directive</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@value)</span> -&gt;</span>
    super()

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      value: <span class="hljs-built_in">Object</span>.assign {},
        @value.ast o
        type: <span class="hljs-string">&#x27;DirectiveLiteral&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-91">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-91">&#x00a7;</a>
              </div>
              <h3 id="literal">Literal</h3>

            </div>
            
        </li>
        
        
        <li id="section-92">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-92">&#x00a7;</a>
              </div>
              <p><code>Literal</code> is a base class for static values that can be passed through
directly into JavaScript without translation, such as: strings, numbers,
<code>true</code>, <code>false</code>, <code>null</code>…</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Literal = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Literal</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@value)</span> -&gt;</span>
    super()

  shouldCache: NO

  assigns: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    name <span class="hljs-keyword">is</span> @value

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [@makeCode @value]

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      value: @value

  toString: <span class="hljs-function">-&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-93">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-93">&#x00a7;</a>
              </div>
              <p>This is only intended for debugging.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-string">&quot; <span class="hljs-subst">#{<span class="hljs-keyword">if</span> @isStatement() <span class="hljs-keyword">then</span> super() <span class="hljs-keyword">else</span> @constructor.name}</span>: <span class="hljs-subst">#{@value}</span>&quot;</span>

<span class="hljs-built_in">exports</span>.NumberLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NumberLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@value, {@parsedValue} = {})</span> -&gt;</span>
    super()
    <span class="hljs-keyword">unless</span> @parsedValue?
      <span class="hljs-keyword">if</span> isNumber @value
        @parsedValue = @value
        @value = <span class="hljs-string">&quot;<span class="hljs-subst">#{@value}</span>&quot;</span>
      <span class="hljs-keyword">else</span>
        @parsedValue = parseNumber @value

  isBigInt: <span class="hljs-function">-&gt;</span>
    <span class="hljs-regexp">/n$/</span>.test @value

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isBigInt()
      <span class="hljs-string">&#x27;BigIntLiteral&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;NumericLiteral&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      value:
        <span class="hljs-keyword">if</span> @isBigInt()
          @parsedValue.toString()
        <span class="hljs-keyword">else</span>
          @parsedValue
      extra:
        rawValue:
          <span class="hljs-keyword">if</span> @isBigInt()
            @parsedValue.toString()
          <span class="hljs-keyword">else</span>
            @parsedValue
        raw: @value

<span class="hljs-built_in">exports</span>.InfinityLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InfinityLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">NumberLiteral</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@value, {@originalValue = <span class="hljs-string">&#x27;Infinity&#x27;</span>} = {})</span> -&gt;</span>
    super()

  compileNode: <span class="hljs-function">-&gt;</span>
    [@makeCode <span class="hljs-string">&#x27;2e308&#x27;</span>]

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">unless</span> @originalValue <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;Infinity&#x27;</span>
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> NumberLiteral(@value).withLocationDataFrom(@).ast o
    super o

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;Identifier&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      name: <span class="hljs-string">&#x27;Infinity&#x27;</span>
      declaration: <span class="hljs-literal">no</span>

<span class="hljs-built_in">exports</span>.NaNLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NaNLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">NumberLiteral</span></span>
  constructor: <span class="hljs-function">-&gt;</span>
    super <span class="hljs-string">&#x27;NaN&#x27;</span>

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    code = [@makeCode <span class="hljs-string">&#x27;0/0&#x27;</span>]
    <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_OP <span class="hljs-keyword">then</span> @wrapInParentheses code <span class="hljs-keyword">else</span> code

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;Identifier&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      name: <span class="hljs-string">&#x27;NaN&#x27;</span>
      declaration: <span class="hljs-literal">no</span>

<span class="hljs-built_in">exports</span>.StringLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StringLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@originalValue, {@quote, @initialChunk, @finalChunk, @indent, @double, @heregex} = {})</span> -&gt;</span>
    super <span class="hljs-string">&#x27;&#x27;</span>
    @quote = <span class="hljs-literal">null</span> <span class="hljs-keyword">if</span> @quote <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;///&#x27;</span>
    @fromSourceString = @quote?
    @quote ?= <span class="hljs-string">&#x27;&quot;&#x27;</span>
    heredoc = @isFromHeredoc()

    val = @originalValue
    <span class="hljs-keyword">if</span> @heregex
      val = val.replace HEREGEX_OMIT, <span class="hljs-string">&#x27;$1$2&#x27;</span>
      val = replaceUnicodeCodePointEscapes val, flags: @heregex.flags
    <span class="hljs-keyword">else</span>
      val = val.replace STRING_OMIT, <span class="hljs-string">&#x27;$1&#x27;</span>
      val =
        <span class="hljs-keyword">unless</span> @fromSourceString
          val
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> heredoc
          indentRegex = <span class="hljs-regexp">/// \n<span class="hljs-subst">#{@indent}</span> ///</span>g <span class="hljs-keyword">if</span> @indent

          val = val.replace indentRegex, <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">if</span> indentRegex
          val = val.replace LEADING_BLANK_LINE,  <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">if</span> @initialChunk
          val = val.replace TRAILING_BLANK_LINE, <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">if</span> @finalChunk
          val
        <span class="hljs-keyword">else</span>
          val.replace SIMPLE_STRING_OMIT, <span class="hljs-function"><span class="hljs-params">(match, offset)</span> =&gt;</span>
            <span class="hljs-keyword">if</span> (@initialChunk <span class="hljs-keyword">and</span> offset <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>) <span class="hljs-keyword">or</span>
               (@finalChunk <span class="hljs-keyword">and</span> offset + match.length <span class="hljs-keyword">is</span> val.length)
              <span class="hljs-string">&#x27;&#x27;</span>
            <span class="hljs-keyword">else</span>
              <span class="hljs-string">&#x27; &#x27;</span>
    @delimiter = @quote.charAt <span class="hljs-number">0</span>
    @value = makeDelimitedLiteral val, {
      @delimiter
      @double
    }

    @unquotedValueForTemplateLiteral = makeDelimitedLiteral val, {
      delimiter: <span class="hljs-string">&#x27;`&#x27;</span>
      @double
      escapeNewlines: <span class="hljs-literal">no</span>
      includeDelimiters: <span class="hljs-literal">no</span>
      convertTrailingNullEscapes: <span class="hljs-literal">yes</span>
    }

    @unquotedValueForJSX = makeDelimitedLiteral val, {
      @double
      escapeNewlines: <span class="hljs-literal">no</span>
      includeDelimiters: <span class="hljs-literal">no</span>
      escapeDelimiter: <span class="hljs-literal">no</span>
    }

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> StringWithInterpolations.fromStringLiteral(@).compileNode o <span class="hljs-keyword">if</span> @shouldGenerateTemplateLiteral()
    <span class="hljs-keyword">return</span> [@makeCode @unquotedValueForJSX] <span class="hljs-keyword">if</span> @jsx
    super o</pre></div></div>
            
        </li>
        
        
        <li id="section-94">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-94">&#x00a7;</a>
              </div>
              <p><code>StringLiteral</code>s can represent either entire literal strings
or pieces of text inside of e.g. an interpolated string.
When parsed as the former but needing to be treated as the latter
(e.g. the string part of a tagged template literal), this will return
a copy of the <code>StringLiteral</code> with the quotes trimmed from its location
data (like it would have if parsed as part of an interpolated string).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  withoutQuotesInLocationData: <span class="hljs-function">-&gt;</span>
    endsWithNewline = @originalValue[<span class="hljs-number">-1.</span>.] <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;\n&#x27;</span>
    locationData = <span class="hljs-built_in">Object</span>.assign {}, @locationData
    locationData.first_column          += @quote.length
    <span class="hljs-keyword">if</span> endsWithNewline
      locationData.last_line -= <span class="hljs-number">1</span>
      locationData.last_column =
        <span class="hljs-keyword">if</span> locationData.last_line <span class="hljs-keyword">is</span> locationData.first_line
          locationData.first_column + @originalValue.length - <span class="hljs-string">&#x27;\n&#x27;</span>.length
        <span class="hljs-keyword">else</span>
          @originalValue[...<span class="hljs-number">-1</span>].length - <span class="hljs-string">&#x27;\n&#x27;</span>.length - @originalValue[...<span class="hljs-number">-1</span>].lastIndexOf(<span class="hljs-string">&#x27;\n&#x27;</span>)
    <span class="hljs-keyword">else</span>
      locationData.last_column         -= @quote.length
    locationData.last_column_exclusive -= @quote.length
    locationData.range = [
      locationData.range[<span class="hljs-number">0</span>] + @quote.length
      locationData.range[<span class="hljs-number">1</span>] - @quote.length
    ]
    copy = <span class="hljs-keyword">new</span> StringLiteral @originalValue, {@quote, @initialChunk, @finalChunk, @indent, @double, @heregex}
    copy.locationData = locationData
    copy

  isFromHeredoc: <span class="hljs-function">-&gt;</span>
    @quote.length <span class="hljs-keyword">is</span> <span class="hljs-number">3</span>

  shouldGenerateTemplateLiteral: <span class="hljs-function">-&gt;</span>
    @isFromHeredoc()

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> StringWithInterpolations.fromStringLiteral(@).ast o <span class="hljs-keyword">if</span> @shouldGenerateTemplateLiteral()
    super o

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      value: @originalValue
      extra:
        raw: <span class="hljs-string">&quot;<span class="hljs-subst">#{@delimiter}</span><span class="hljs-subst">#{@originalValue}</span><span class="hljs-subst">#{@delimiter}</span>&quot;</span>

<span class="hljs-built_in">exports</span>.RegexLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RegexLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(value, {@delimiter = <span class="hljs-string">&#x27;/&#x27;</span>, @heregexCommentTokens = []} = {})</span> -&gt;</span>
    super <span class="hljs-string">&#x27;&#x27;</span>
    heregex = @delimiter <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;///&#x27;</span>
    endDelimiterIndex = value.lastIndexOf <span class="hljs-string">&#x27;/&#x27;</span>
    @flags = value[endDelimiterIndex + <span class="hljs-number">1.</span>.]
    val = @originalValue = value[<span class="hljs-number">1.</span>..endDelimiterIndex]
    val = val.replace HEREGEX_OMIT, <span class="hljs-string">&#x27;$1$2&#x27;</span> <span class="hljs-keyword">if</span> heregex
    val = replaceUnicodeCodePointEscapes val, {@flags}
    @value = <span class="hljs-string">&quot;<span class="hljs-subst">#{makeDelimitedLiteral val, delimiter: <span class="hljs-string">&#x27;/&#x27;</span>}</span><span class="hljs-subst">#{@flags}</span>&quot;</span>

  REGEX_REGEX: <span class="hljs-regexp">/// ^ / (.*) / \w* $ ///</span>

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;RegExpLiteral&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [, pattern] = @REGEX_REGEX.exec @value
    <span class="hljs-keyword">return</span> {
      value: <span class="hljs-literal">undefined</span>
      pattern, @flags, @delimiter
      originalPattern: @originalValue
      extra:
        raw: @value
        originalRaw: <span class="hljs-string">&quot;<span class="hljs-subst">#{@delimiter}</span><span class="hljs-subst">#{@originalValue}</span><span class="hljs-subst">#{@delimiter}</span><span class="hljs-subst">#{@flags}</span>&quot;</span>
        rawValue: <span class="hljs-literal">undefined</span>
      comments:
        <span class="hljs-keyword">for</span> heregexCommentToken <span class="hljs-keyword">in</span> @heregexCommentTokens
          <span class="hljs-keyword">if</span> heregexCommentToken.here
            <span class="hljs-keyword">new</span> HereComment(heregexCommentToken).ast o
          <span class="hljs-keyword">else</span>
            <span class="hljs-keyword">new</span> LineComment(heregexCommentToken).ast o
    }

<span class="hljs-built_in">exports</span>.PassthroughLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PassthroughLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@originalValue, {@here, @generated} = {})</span> -&gt;</span>
    super <span class="hljs-string">&#x27;&#x27;</span>
    @value = @originalValue.replace <span class="hljs-regexp">/\\+(`|$)/g</span>, <span class="hljs-function"><span class="hljs-params">(string)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-95">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-95">&#x00a7;</a>
              </div>
              <p><code>string</code> is always a value like ‘`‘, ‘\`‘, ‘\\`‘, etc.
By reducing it to its latter half, we turn ‘`‘ to ‘<code>&#39;, &#39;\\\</code>‘ to ‘`‘, etc.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      string[-<span class="hljs-built_in">Math</span>.ceil(string.length / <span class="hljs-number">2</span>)..]

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span> <span class="hljs-keyword">if</span> @generated
    super o

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> {
      value: @originalValue
      here: !!@here
    }

<span class="hljs-built_in">exports</span>.IdentifierLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IdentifierLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  isAssignable: YES

  eachName: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span>
    iterator @

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @jsx
      <span class="hljs-string">&#x27;JSXIdentifier&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;Identifier&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      name: @value
      declaration: !!@isDeclaration

<span class="hljs-built_in">exports</span>.PropertyName = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PropertyName</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  isAssignable: YES

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @jsx
      <span class="hljs-string">&#x27;JSXIdentifier&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;Identifier&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      name: @value
      declaration: <span class="hljs-literal">no</span>

<span class="hljs-built_in">exports</span>.ComputedPropertyName = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ComputedPropertyName</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PropertyName</span></span>
  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [@makeCode(<span class="hljs-string">&#x27;[&#x27;</span>), @value.compileToFragments(o, LEVEL_LIST)..., @makeCode(<span class="hljs-string">&#x27;]&#x27;</span>)]

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @value.ast o

<span class="hljs-built_in">exports</span>.StatementLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StatementLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  isStatement: YES

  makeReturn: THIS

  jumps: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> this <span class="hljs-keyword">if</span> @value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;break&#x27;</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> (o?.<span class="hljs-keyword">loop</span> <span class="hljs-keyword">or</span> o?.block)
    <span class="hljs-keyword">return</span> this <span class="hljs-keyword">if</span> @value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;continue&#x27;</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> o?.<span class="hljs-keyword">loop</span>

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [@makeCode <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span><span class="hljs-subst">#{@value}</span>;&quot;</span>]

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">switch</span> @value
      <span class="hljs-keyword">when</span> <span class="hljs-string">&#x27;continue&#x27;</span> <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;ContinueStatement&#x27;</span>
      <span class="hljs-keyword">when</span> <span class="hljs-string">&#x27;break&#x27;</span>    <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;BreakStatement&#x27;</span>
      <span class="hljs-keyword">when</span> <span class="hljs-string">&#x27;debugger&#x27;</span> <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;DebuggerStatement&#x27;</span>

<span class="hljs-built_in">exports</span>.ThisLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ThisLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(value)</span> -&gt;</span>
    super <span class="hljs-string">&#x27;this&#x27;</span>
    @shorthand = value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;@&#x27;</span>

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    code = <span class="hljs-keyword">if</span> o.scope.method?.bound <span class="hljs-keyword">then</span> o.scope.method.context <span class="hljs-keyword">else</span> @value
    [@makeCode code]

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;ThisExpression&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      shorthand: @shorthand

<span class="hljs-built_in">exports</span>.UndefinedLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UndefinedLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  constructor: <span class="hljs-function">-&gt;</span>
    super <span class="hljs-string">&#x27;undefined&#x27;</span>

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [@makeCode <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_ACCESS <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;(void 0)&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;void 0&#x27;</span>]

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;Identifier&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      name: @value
      declaration: <span class="hljs-literal">no</span>

<span class="hljs-built_in">exports</span>.NullLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NullLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  constructor: <span class="hljs-function">-&gt;</span>
    super <span class="hljs-string">&#x27;null&#x27;</span>

<span class="hljs-built_in">exports</span>.BooleanLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BooleanLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(value, {@originalValue} = {})</span> -&gt;</span>
    super value
    @originalValue ?= @value

  astProperties: <span class="hljs-function">-&gt;</span>
    value: <span class="hljs-keyword">if</span> @value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;true&#x27;</span> <span class="hljs-keyword">then</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">else</span> <span class="hljs-literal">no</span>
    name: @originalValue

<span class="hljs-built_in">exports</span>.DefaultLiteral = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DefaultLiteral</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Literal</span></span>
  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;Identifier&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      name: <span class="hljs-string">&#x27;default&#x27;</span>
      declaration: <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-96">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-96">&#x00a7;</a>
              </div>
              <h3 id="return">Return</h3>

            </div>
            
        </li>
        
        
        <li id="section-97">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-97">&#x00a7;</a>
              </div>
              <p>A <code>return</code> is a <em>pureStatement</em>—wrapping it in a closure wouldn’t make sense.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Return = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Return</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@expression, {@belongsToFuncDirectiveReturn} = {})</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;expression&#x27;</span>]

  isStatement:     YES
  makeReturn:      THIS
  jumps:           THIS

  compileToFragments: <span class="hljs-function"><span class="hljs-params">(o, level)</span> -&gt;</span>
    expr = @expression?.makeReturn()
    <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">and</span> expr <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Return <span class="hljs-keyword">then</span> expr.compileToFragments o, level <span class="hljs-keyword">else</span> super o, level

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    answer = []</pre></div></div>
            
        </li>
        
        
        <li id="section-98">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-98">&#x00a7;</a>
              </div>
              <p>TODO: If we call <code>expression.compile()</code> here twice, we’ll sometimes
get back different results!</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @expression
      answer = @expression.compileToFragments o, LEVEL_PAREN
      unshiftAfterComments answer, @makeCode <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span>return &quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-99">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-99">&#x00a7;</a>
              </div>
              <p>Since the <code>return</code> got indented by <code>@tab</code>, preceding comments that are
multiline need to be indented.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">for</span> fragment <span class="hljs-keyword">in</span> answer
        <span class="hljs-keyword">if</span> fragment.isHereComment <span class="hljs-keyword">and</span> <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">in</span> fragment.code
          fragment.code = multident fragment.code, @tab
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> fragment.isLineComment
          fragment.code = <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span><span class="hljs-subst">#{fragment.code}</span>&quot;</span>
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">break</span>
    <span class="hljs-keyword">else</span>
      answer.push @makeCode <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span>return&quot;</span>
    answer.push @makeCode <span class="hljs-string">&#x27;;&#x27;</span>
    answer

  checkForPureStatementInExpression: <span class="hljs-function">-&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-100">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-100">&#x00a7;</a>
              </div>
              <p>don’t flag <code>return</code> from <code>await return</code>/<code>yield return</code> as invalid.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> @belongsToFuncDirectiveReturn
    super()

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;ReturnStatement&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    argument: @expression?.ast(o, LEVEL_PAREN) ? <span class="hljs-literal">null</span></pre></div></div>
            
        </li>
        
        
        <li id="section-101">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-101">&#x00a7;</a>
              </div>
              <p>Parent class for <code>YieldReturn</code>/<code>AwaitReturn</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.FuncDirectiveReturn = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FuncDirectiveReturn</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Return</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(expression, {@returnKeyword})</span> -&gt;</span>
    super expression

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkScope o
    super o

  checkScope: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">unless</span> o.scope.parent?
      @error <span class="hljs-string">&quot;<span class="hljs-subst">#{@keyword}</span> can only occur inside functions&quot;</span>

  isStatementAst: NO

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkScope o

    <span class="hljs-keyword">new</span> Op @keyword,
      <span class="hljs-keyword">new</span> Return @expression, belongsToFuncDirectiveReturn: <span class="hljs-literal">yes</span>
      .withLocationDataFrom(
        <span class="hljs-keyword">if</span> @expression?
          locationData: mergeLocationData @returnKeyword.locationData, @expression.locationData
        <span class="hljs-keyword">else</span>
          @returnKeyword
      )
    .withLocationDataFrom @
    .ast o</pre></div></div>
            
        </li>
        
        
        <li id="section-102">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-102">&#x00a7;</a>
              </div>
              <p><code>yield return</code> works exactly like <code>return</code>, except that it turns the function
into a generator.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.YieldReturn = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">YieldReturn</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">FuncDirectiveReturn</span></span>
  keyword: <span class="hljs-string">&#x27;yield&#x27;</span>

<span class="hljs-built_in">exports</span>.AwaitReturn = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AwaitReturn</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">FuncDirectiveReturn</span></span>
  keyword: <span class="hljs-string">&#x27;await&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-103">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-103">&#x00a7;</a>
              </div>
              <h3 id="value">Value</h3>

            </div>
            
        </li>
        
        
        <li id="section-104">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-104">&#x00a7;</a>
              </div>
              <p>A value, variable or literal or parenthesized, indexed or dotted into,
or vanilla.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Value = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Value</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(base, props, tag, isDefaultValue = <span class="hljs-literal">no</span>)</span> -&gt;</span>
    super()
    <span class="hljs-keyword">return</span> base <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> props <span class="hljs-keyword">and</span> base <span class="hljs-keyword">instanceof</span> Value
    @base           = base
    @properties     = props <span class="hljs-keyword">or</span> []
    @tag            = tag
    @[tag]          = <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> tag
    @isDefaultValue = isDefaultValue</pre></div></div>
            
        </li>
        
        
        <li id="section-105">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-105">&#x00a7;</a>
              </div>
              <p>If this is a <code>@foo =</code> assignment, if there are comments on <code>@</code> move them
to be on <code>foo</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @base?.comments <span class="hljs-keyword">and</span> @base <span class="hljs-keyword">instanceof</span> ThisLiteral <span class="hljs-keyword">and</span> @properties[<span class="hljs-number">0</span>]?.name?
      moveComments @base, @properties[<span class="hljs-number">0</span>].name

  children: [<span class="hljs-string">&#x27;base&#x27;</span>, <span class="hljs-string">&#x27;properties&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-106">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-106">&#x00a7;</a>
              </div>
              <p>Add a property (or <em>properties</em> ) <code>Access</code> to the list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  add: <span class="hljs-function"><span class="hljs-params">(props)</span> -&gt;</span>
    @properties = @properties.concat props
    @forceUpdateLocation = <span class="hljs-literal">yes</span>
    this

  hasProperties: <span class="hljs-function">-&gt;</span>
    @properties.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>

  bareLiteral: <span class="hljs-function"><span class="hljs-params">(type)</span> -&gt;</span>
    <span class="hljs-keyword">not</span> @properties.length <span class="hljs-keyword">and</span> @base <span class="hljs-keyword">instanceof</span> type</pre></div></div>
            
        </li>
        
        
        <li id="section-107">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-107">&#x00a7;</a>
              </div>
              <p>Some boolean checks for the benefit of other nodes.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  isArray        : <span class="hljs-function">-&gt;</span> @bareLiteral(Arr)
  isRange        : <span class="hljs-function">-&gt;</span> @bareLiteral(Range)
  shouldCache    : <span class="hljs-function">-&gt;</span> @hasProperties() <span class="hljs-keyword">or</span> @base.shouldCache()
  isAssignable   : <span class="hljs-function"><span class="hljs-params">(opts)</span> -&gt;</span> @hasProperties() <span class="hljs-keyword">or</span> @base.isAssignable opts
  isNumber       : <span class="hljs-function">-&gt;</span> @bareLiteral(NumberLiteral)
  isString       : <span class="hljs-function">-&gt;</span> @bareLiteral(StringLiteral)
  isRegex        : <span class="hljs-function">-&gt;</span> @bareLiteral(RegexLiteral)
  isUndefined    : <span class="hljs-function">-&gt;</span> @bareLiteral(UndefinedLiteral)
  isNull         : <span class="hljs-function">-&gt;</span> @bareLiteral(NullLiteral)
  isBoolean      : <span class="hljs-function">-&gt;</span> @bareLiteral(BooleanLiteral)
  isAtomic       : <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> @properties.concat @base
      <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">if</span> node.soak <span class="hljs-keyword">or</span> node <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">or</span> node <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> node.operator <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;do&#x27;</span>
    <span class="hljs-literal">yes</span>

  isNotCallable  : <span class="hljs-function">-&gt;</span> @isNumber() <span class="hljs-keyword">or</span> @isString() <span class="hljs-keyword">or</span> @isRegex() <span class="hljs-keyword">or</span>
                      @isArray() <span class="hljs-keyword">or</span> @isRange() <span class="hljs-keyword">or</span> @isSplice() <span class="hljs-keyword">or</span> @isObject() <span class="hljs-keyword">or</span>
                      @isUndefined() <span class="hljs-keyword">or</span> @isNull() <span class="hljs-keyword">or</span> @isBoolean()

  isStatement : <span class="hljs-function"><span class="hljs-params">(o)</span>    -&gt;</span> <span class="hljs-keyword">not</span> @properties.length <span class="hljs-keyword">and</span> @base.isStatement o
  isJSXTag    : <span class="hljs-function">-&gt;</span> @base <span class="hljs-keyword">instanceof</span> JSXTag
  assigns     : <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span> <span class="hljs-keyword">not</span> @properties.length <span class="hljs-keyword">and</span> @base.assigns name
  jumps       : <span class="hljs-function"><span class="hljs-params">(o)</span>    -&gt;</span> <span class="hljs-keyword">not</span> @properties.length <span class="hljs-keyword">and</span> @base.jumps o

  isObject: <span class="hljs-function"><span class="hljs-params">(onlyGenerated)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">if</span> @properties.length
    (@base <span class="hljs-keyword">instanceof</span> Obj) <span class="hljs-keyword">and</span> (<span class="hljs-keyword">not</span> onlyGenerated <span class="hljs-keyword">or</span> @base.generated)

  isElision: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> @base <span class="hljs-keyword">instanceof</span> Arr
    @base.hasElision()

  isSplice: <span class="hljs-function">-&gt;</span>
    [..., lastProperty] = @properties
    lastProperty <span class="hljs-keyword">instanceof</span> Slice

  looksStatic: <span class="hljs-function"><span class="hljs-params">(className)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> ((thisLiteral = @base) <span class="hljs-keyword">instanceof</span> ThisLiteral <span class="hljs-keyword">or</span> (name = @base).value <span class="hljs-keyword">is</span> className) <span class="hljs-keyword">and</span>
      @properties.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> @properties[<span class="hljs-number">0</span>].name?.value <span class="hljs-keyword">isnt</span> <span class="hljs-string">&#x27;prototype&#x27;</span>
    <span class="hljs-keyword">return</span>
      staticClassName: thisLiteral ? name</pre></div></div>
            
        </li>
        
        
        <li id="section-108">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-108">&#x00a7;</a>
              </div>
              <p>The value can be unwrapped as its inner node, if there are no attached
properties.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  unwrap: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @properties.length <span class="hljs-keyword">then</span> this <span class="hljs-keyword">else</span> @base</pre></div></div>
            
        </li>
        
        
        <li id="section-109">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-109">&#x00a7;</a>
              </div>
              <p>A reference has base part (<code>this</code> value) and name part.
We cache them separately for compiling complex expressions.
<code>a()[b()] ?= c</code> -&gt; <code>(_base = a())[_name = b()] ? _base[_name] = c</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  cacheReference: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [..., name] = @properties
    <span class="hljs-keyword">if</span> @properties.length &lt; <span class="hljs-number">2</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @base.shouldCache() <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> name?.shouldCache()
      <span class="hljs-keyword">return</span> [this, this]  <span class="hljs-comment"># `a` `a.b`</span>
    base = <span class="hljs-keyword">new</span> Value @base, @properties[...<span class="hljs-number">-1</span>]
    <span class="hljs-keyword">if</span> base.shouldCache()  <span class="hljs-comment"># `a().b`</span>
      bref = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;base&#x27;</span>
      base = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Assign bref, base
    <span class="hljs-keyword">return</span> [base, bref] <span class="hljs-keyword">unless</span> name  <span class="hljs-comment"># `a()`</span>
    <span class="hljs-keyword">if</span> name.shouldCache()  <span class="hljs-comment"># `a[b()]`</span>
      nref = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;name&#x27;</span>
      name = <span class="hljs-keyword">new</span> Index <span class="hljs-keyword">new</span> Assign nref, name.index
      nref = <span class="hljs-keyword">new</span> Index nref
    [base.add(name), <span class="hljs-keyword">new</span> Value(bref <span class="hljs-keyword">or</span> base.base, [nref <span class="hljs-keyword">or</span> name])]</pre></div></div>
            
        </li>
        
        
        <li id="section-110">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-110">&#x00a7;</a>
              </div>
              <p>We compile a value to JavaScript by compiling and joining each property.
Things get much more interesting if the chain of properties has <em>soak</em>
operators <code>?.</code> interspersed. Then we have to take care not to accidentally
evaluate anything twice when building the soak chain.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @base.front = @front
    props = @properties
    <span class="hljs-keyword">if</span> props.length <span class="hljs-keyword">and</span> @base.cached?</pre></div></div>
            
        </li>
        
        
        <li id="section-111">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-111">&#x00a7;</a>
              </div>
              <p>Cached fragments enable correct order of the compilation,
and reuse of variables in the scope.
Example:
<code>a(x = 5).b(-&gt; x = 6)</code> should compile in the same order as
<code>a(x = 5); b(-&gt; x = 6)</code>
(see issue #4437, <a href="https://github.com/jashkenas/coffeescript/issues/4437">https://github.com/jashkenas/coffeescript/issues/4437</a>)</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      fragments = @base.cached
    <span class="hljs-keyword">else</span>
      fragments = @base.compileToFragments o, (<span class="hljs-keyword">if</span> props.length <span class="hljs-keyword">then</span> LEVEL_ACCESS <span class="hljs-keyword">else</span> <span class="hljs-literal">null</span>)
    <span class="hljs-keyword">if</span> props.length <span class="hljs-keyword">and</span> SIMPLENUM.test fragmentsToText fragments
      fragments.push @makeCode <span class="hljs-string">&#x27;.&#x27;</span>
    <span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> props
      fragments.push (prop.compileToFragments o)...

    fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-112">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-112">&#x00a7;</a>
              </div>
              <p>Unfold a soak into an <code>If</code>: <code>a?.b</code> -&gt; <code>a.b if a?</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  unfoldSoak: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @unfoldedSoak ?= <span class="hljs-keyword">do</span> =&gt;
      ifn = @base.unfoldSoak o
      <span class="hljs-keyword">if</span> ifn
        ifn.body.properties.push @properties...
        <span class="hljs-keyword">return</span> ifn
      <span class="hljs-keyword">for</span> prop, i <span class="hljs-keyword">in</span> @properties <span class="hljs-keyword">when</span> prop.soak
        prop.soak = <span class="hljs-literal">off</span>
        fst = <span class="hljs-keyword">new</span> Value @base, @properties[...i]
        snd = <span class="hljs-keyword">new</span> Value @base, @properties[i..]
        <span class="hljs-keyword">if</span> fst.shouldCache()
          ref = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;ref&#x27;</span>
          fst = <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Assign ref, fst
          snd.base = ref
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> If <span class="hljs-keyword">new</span> Existence(fst), snd, soak: <span class="hljs-literal">on</span>
      <span class="hljs-literal">no</span>

  eachName: <span class="hljs-function"><span class="hljs-params">(iterator, {checkAssignability = <span class="hljs-literal">yes</span>} = {})</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @hasProperties()
      iterator @
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> checkAssignability <span class="hljs-keyword">or</span> @base.isAssignable()
      @base.eachName iterator
    <span class="hljs-keyword">else</span>
      @error <span class="hljs-string">&#x27;tried to assign to unassignable value&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-113">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-113">&#x00a7;</a>
              </div>
              <p>For AST generation, we need an <code>object</code> that’s this <code>Value</code> minus its last
property, if it has properties.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  object: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> @ <span class="hljs-keyword">unless</span> @hasProperties()</pre></div></div>
            
        </li>
        
        
        <li id="section-114">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-114">&#x00a7;</a>
              </div>
              <p>Get all properties except the last one; for a <code>Value</code> with only one
property, <code>initialProperties</code> is an empty array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    initialProperties = @properties[<span class="hljs-number">0.</span>..@properties.length - <span class="hljs-number">1</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-115">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-115">&#x00a7;</a>
              </div>
              <p>Create the <code>object</code> that becomes the new “base” for the split-off final
property.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    object = <span class="hljs-keyword">new</span> Value @base, initialProperties, @tag, @isDefaultValue</pre></div></div>
            
        </li>
        
        
        <li id="section-116">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-116">&#x00a7;</a>
              </div>
              <p>Add location data to our new node, so that it has correct location data
for source maps or later conversion into AST location data.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    object.locationData =
      <span class="hljs-keyword">if</span> initialProperties.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span></pre></div></div>
            
        </li>
        
        
        <li id="section-117">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-117">&#x00a7;</a>
              </div>
              <p>This new <code>Value</code> has only one property, so the location data is just
that of the parent <code>Value</code>’s base.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        @base.locationData
      <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-118">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-118">&#x00a7;</a>
              </div>
              <p>This new <code>Value</code> has multiple properties, so the location data spans
from the parent <code>Value</code>’s base to the last property that’s included
in this new node (a.k.a. the second-to-last property of the parent).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        mergeLocationData @base.locationData, initialProperties[initialProperties.length - <span class="hljs-number">1</span>].locationData
    object

  containsSoak: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> @hasProperties()

    <span class="hljs-keyword">for</span> property <span class="hljs-keyword">in</span> @properties <span class="hljs-keyword">when</span> property.soak
      <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>

    <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @base <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">and</span> @base.soak

    <span class="hljs-literal">no</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-119">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-119">&#x00a7;</a>
              </div>
              <p>If the <code>Value</code> has no properties, the AST node is just whatever this
node’s <code>base</code> is.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">return</span> @base.ast o <span class="hljs-keyword">unless</span> @hasProperties()</pre></div></div>
            
        </li>
        
        
        <li id="section-120">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-120">&#x00a7;</a>
              </div>
              <p>Otherwise, call <code>Base::ast</code> which in turn calls the <code>astType</code> and
<code>astProperties</code> methods below.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    super o

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isJSXTag()
      <span class="hljs-string">&#x27;JSXMemberExpression&#x27;</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @containsSoak()
      <span class="hljs-string">&#x27;OptionalMemberExpression&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;MemberExpression&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-121">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-121">&#x00a7;</a>
              </div>
              <p>If this <code>Value</code> has properties, the <em>last</em> property (e.g. <code>c</code> in <code>a.b.c</code>)
becomes the <code>property</code>, and the preceding properties (e.g. <code>a.b</code>) become
a child <code>Value</code> node assigned to the <code>object</code> property.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [..., property] = @properties
    property.name.jsx = <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @isJSXTag()
    computed = property <span class="hljs-keyword">instanceof</span> Index <span class="hljs-keyword">or</span> property.name?.unwrap() <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> PropertyName
    <span class="hljs-keyword">return</span> {
      object: @object().ast o, LEVEL_ACCESS
      property: property.ast o, (LEVEL_PAREN <span class="hljs-keyword">if</span> computed)
      computed
      optional: !!property.soak
      shorthand: !!property.shorthand
    }

  astLocationData: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> super() <span class="hljs-keyword">unless</span> @isJSXTag()</pre></div></div>
            
        </li>
        
        
        <li id="section-122">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-122">&#x00a7;</a>
              </div>
              <p>don’t include leading &lt; of JSX tag in location data</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    mergeAstLocationData(
      jisonLocationDataToAstLocationData(@base.tagNameLocationData),
      jisonLocationDataToAstLocationData(@properties[@properties.length - <span class="hljs-number">1</span>].locationData)
    )

<span class="hljs-built_in">exports</span>.MetaProperty = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MetaProperty</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@meta, @property)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;meta&#x27;</span>, <span class="hljs-string">&#x27;property&#x27;</span>]

  checkValid: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @meta.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;new&#x27;</span>
      <span class="hljs-keyword">if</span> @property <span class="hljs-keyword">instanceof</span> Access <span class="hljs-keyword">and</span> @property.name.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;target&#x27;</span>
        <span class="hljs-keyword">unless</span> o.scope.parent?
          @error <span class="hljs-string">&quot;new.target can only occur inside functions&quot;</span>
      <span class="hljs-keyword">else</span>
        @error <span class="hljs-string">&quot;the only valid meta property for new is new.target&quot;</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @meta.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;import&#x27;</span>
      <span class="hljs-keyword">unless</span> @property <span class="hljs-keyword">instanceof</span> Access <span class="hljs-keyword">and</span> @property.name.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;meta&#x27;</span>
        @error <span class="hljs-string">&quot;the only valid meta property for import is import.meta&quot;</span>

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkValid o
    fragments = []
    fragments.push @meta.compileToFragments(o, LEVEL_ACCESS)...
    fragments.push @property.compileToFragments(o)...
    fragments

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkValid o

    <span class="hljs-keyword">return</span>
      meta: @meta.ast o, LEVEL_ACCESS
      property: @property.ast o</pre></div></div>
            
        </li>
        
        
        <li id="section-123">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-123">&#x00a7;</a>
              </div>
              <h3 id="herecomment">HereComment</h3>

            </div>
            
        </li>
        
        
        <li id="section-124">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-124">&#x00a7;</a>
              </div>
              <p>Comment delimited by <code>###</code> (becoming <code>/* */</code>).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.HereComment = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HereComment</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">({ @content, @newLine, @unshift, @locationData })</span> -&gt;</span>
    super()

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    multiline = <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">in</span> @content</pre></div></div>
            
        </li>
        
        
        <li id="section-125">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-125">&#x00a7;</a>
              </div>
              <p>Unindent multiline comments. They will be reindented later.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> multiline
      indent = <span class="hljs-literal">null</span>
      <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> @content.split <span class="hljs-string">&#x27;\n&#x27;</span>
        leadingWhitespace = <span class="hljs-regexp">/^\s*/</span>.exec(line)[<span class="hljs-number">0</span>]
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> indent <span class="hljs-keyword">or</span> leadingWhitespace.length &lt; indent.length
          indent = leadingWhitespace
      @content = @content.replace <span class="hljs-regexp">/// \n <span class="hljs-subst">#{indent}</span> ///</span>g, <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">if</span> indent

    hasLeadingMarks = <span class="hljs-regexp">/\n\s*[#|\*]/</span>.test @content
    @content = @content.replace <span class="hljs-regexp">/^([ \t]*)#(?=\s)/gm</span>, <span class="hljs-string">&#x27; *&#x27;</span> <span class="hljs-keyword">if</span> hasLeadingMarks

    @content = <span class="hljs-string">&quot;/*<span class="hljs-subst">#{@content}</span><span class="hljs-subst">#{<span class="hljs-keyword">if</span> hasLeadingMarks <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27; &#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>}</span>*/&quot;</span>
    fragment = @makeCode @content
    fragment.newLine = @newLine
    fragment.unshift = @unshift
    fragment.multiline = multiline</pre></div></div>
            
        </li>
        
        
        <li id="section-126">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-126">&#x00a7;</a>
              </div>
              <p>Don’t rely on <code>fragment.type</code>, which can break when the compiler is minified.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    fragment.isComment = fragment.isHereComment = <span class="hljs-literal">yes</span>
    fragment

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;CommentBlock&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      value: @content</pre></div></div>
            
        </li>
        
        
        <li id="section-127">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-127">&#x00a7;</a>
              </div>
              <h3 id="linecomment">LineComment</h3>

            </div>
            
        </li>
        
        
        <li id="section-128">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-128">&#x00a7;</a>
              </div>
              <p>Comment running from <code>#</code> to the end of a line (becoming <code>//</code>).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.LineComment = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LineComment</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">({ @content, @newLine, @unshift, @locationData, @precededByBlankLine })</span> -&gt;</span>
    super()

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    fragment = @makeCode(<span class="hljs-keyword">if</span> <span class="hljs-regexp">/^\s*$/</span>.test @content <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{<span class="hljs-keyword">if</span> @precededByBlankLine <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;\n<span class="hljs-subst">#{o.indent}</span>&quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>}</span>//<span class="hljs-subst">#{@content}</span>&quot;</span>)
    fragment.newLine = @newLine
    fragment.unshift = @unshift
    fragment.trail = <span class="hljs-keyword">not</span> @newLine <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @unshift</pre></div></div>
            
        </li>
        
        
        <li id="section-129">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-129">&#x00a7;</a>
              </div>
              <p>Don’t rely on <code>fragment.type</code>, which can break when the compiler is minified.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    fragment.isComment = fragment.isLineComment = <span class="hljs-literal">yes</span>
    fragment

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;CommentLine&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      value: @content</pre></div></div>
            
        </li>
        
        
        <li id="section-130">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-130">&#x00a7;</a>
              </div>
              <h3 id="jsx">JSX</h3>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-built_in">exports</span>.JSXIdentifier = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXIdentifier</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">IdentifierLiteral</span></span>
  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;JSXIdentifier&#x27;</span>

<span class="hljs-built_in">exports</span>.JSXTag = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXTag</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">JSXIdentifier</span></span>
  constructor: (value, {
    @tagNameLocationData
    @closingTagOpeningBracketLocationData
    @closingTagSlashLocationData
    @closingTagNameLocationData
    @closingTagClosingBracketLocationData
  }) -&gt;
    super value

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      name: @value

<span class="hljs-built_in">exports</span>.JSXExpressionContainer = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXExpressionContainer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@expression, {locationData} = {})</span> -&gt;</span>
    super()
    @expression.jsxAttribute = <span class="hljs-literal">yes</span>
    @locationData = locationData ? @expression.locationData

  children: [<span class="hljs-string">&#x27;expression&#x27;</span>]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @expression.compileNode(o)

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      expression: astAsBlockIfNeeded @expression, o

<span class="hljs-built_in">exports</span>.JSXEmptyExpression = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXEmptyExpression</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

<span class="hljs-built_in">exports</span>.JSXText = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXText</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(stringLiteral)</span> -&gt;</span>
    super()
    @value = stringLiteral.unquotedValueForJSX
    @locationData = stringLiteral.locationData

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> {
      @value
      extra:
        raw: @value
    }

<span class="hljs-built_in">exports</span>.JSXAttribute = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXAttribute</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">({@name, value})</span> -&gt;</span>
    super()
    @value =
      <span class="hljs-keyword">if</span> value?
        value = value.base
        <span class="hljs-keyword">if</span> value <span class="hljs-keyword">instanceof</span> StringLiteral <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> value.shouldGenerateTemplateLiteral()
          value
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">new</span> JSXExpressionContainer value
      <span class="hljs-keyword">else</span>
        <span class="hljs-literal">null</span>
    @value?.comments = value.comments

  children: [<span class="hljs-string">&#x27;name&#x27;</span>, <span class="hljs-string">&#x27;value&#x27;</span>]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    compiledName = @name.compileToFragments o, LEVEL_LIST
    <span class="hljs-keyword">return</span> compiledName <span class="hljs-keyword">unless</span> @value?
    val = @value.compileToFragments o, LEVEL_LIST
    compiledName.concat @makeCode(<span class="hljs-string">&#x27;=&#x27;</span>), val

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    name = @name
    <span class="hljs-keyword">if</span> <span class="hljs-string">&#x27;:&#x27;</span> <span class="hljs-keyword">in</span> name.value
      name = <span class="hljs-keyword">new</span> JSXNamespacedName name
    <span class="hljs-keyword">return</span>
      name: name.ast o
      value: @value?.ast(o) ? <span class="hljs-literal">null</span>

<span class="hljs-built_in">exports</span>.JSXAttributes = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXAttributes</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(arr)</span> -&gt;</span>
    super()
    @attributes = []
    <span class="hljs-keyword">for</span> object <span class="hljs-keyword">in</span> arr.objects
      @checkValidAttribute object
      {base} = object
      <span class="hljs-keyword">if</span> base <span class="hljs-keyword">instanceof</span> IdentifierLiteral</pre></div></div>
            
        </li>
        
        
        <li id="section-131">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-131">&#x00a7;</a>
              </div>
              <p>attribute with no value eg disabled</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        attribute = <span class="hljs-keyword">new</span> JSXAttribute name: <span class="hljs-keyword">new</span> JSXIdentifier(base.value).withLocationDataAndCommentsFrom base
        attribute.locationData = base.locationData
        @attributes.push attribute
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> base.generated</pre></div></div>
            
        </li>
        
        
        <li id="section-132">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-132">&#x00a7;</a>
              </div>
              <p>object spread attribute eg {…props}</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        attribute = base.properties[<span class="hljs-number">0</span>]
        attribute.jsx = <span class="hljs-literal">yes</span>
        attribute.locationData = base.locationData
        @attributes.push attribute
      <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-133">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-133">&#x00a7;</a>
              </div>
              <p>Obj containing attributes with values eg a=”b” c={d}</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">for</span> property <span class="hljs-keyword">in</span> base.properties
          {variable, value} = property
          attribute = <span class="hljs-keyword">new</span> JSXAttribute {
            name: <span class="hljs-keyword">new</span> JSXIdentifier(variable.base.value).withLocationDataAndCommentsFrom variable.base
            value
          }
          attribute.locationData = property.locationData
          @attributes.push attribute
    @locationData = arr.locationData

  children: [<span class="hljs-string">&#x27;attributes&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-134">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-134">&#x00a7;</a>
              </div>
              <p>Catch invalid attributes: &lt;div {a:”b”, props} {props} “value” /&gt;</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  checkValidAttribute: <span class="hljs-function"><span class="hljs-params">(object)</span> -&gt;</span>
    {base: attribute} = object
    properties = attribute?.properties <span class="hljs-keyword">or</span> []
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> (attribute <span class="hljs-keyword">instanceof</span> Obj <span class="hljs-keyword">or</span> attribute <span class="hljs-keyword">instanceof</span> IdentifierLiteral) <span class="hljs-keyword">or</span> (attribute <span class="hljs-keyword">instanceof</span> Obj <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> attribute.generated <span class="hljs-keyword">and</span> (properties.length &gt; <span class="hljs-number">1</span> <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> (properties[<span class="hljs-number">0</span>] <span class="hljs-keyword">instanceof</span> Splat)))
      object.error <span class="hljs-string">&quot;&quot;&quot;
        Unexpected token. Allowed JSX attributes are: id=&quot;val&quot;, src={source}, {props...} or attribute.
      &quot;&quot;&quot;</span>

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    fragments = []
    <span class="hljs-keyword">for</span> attribute <span class="hljs-keyword">in</span> @attributes
      fragments.push @makeCode <span class="hljs-string">&#x27; &#x27;</span>
      fragments.push attribute.compileToFragments(o, LEVEL_TOP)...
    fragments

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    attribute.ast(o) <span class="hljs-keyword">for</span> attribute <span class="hljs-keyword">in</span> @attributes

<span class="hljs-built_in">exports</span>.JSXNamespacedName = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXNamespacedName</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(tag)</span> -&gt;</span>
    super()
    [namespace, name] = tag.value.split <span class="hljs-string">&#x27;:&#x27;</span>
    @namespace = <span class="hljs-keyword">new</span> JSXIdentifier(namespace).withLocationDataFrom locationData: extractSameLineLocationDataFirst(namespace.length) tag.locationData
    @name      = <span class="hljs-keyword">new</span> JSXIdentifier(name     ).withLocationDataFrom locationData: extractSameLineLocationDataLast(name.length      ) tag.locationData
    @locationData = tag.locationData

  children: [<span class="hljs-string">&#x27;namespace&#x27;</span>, <span class="hljs-string">&#x27;name&#x27;</span>]

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      namespace: @namespace.ast o
      name: @name.ast o</pre></div></div>
            
        </li>
        
        
        <li id="section-135">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-135">&#x00a7;</a>
              </div>
              <p>Node for a JSX element</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.JSXElement = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JSXElement</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">({@tagName, @attributes, @content})</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;tagName&#x27;</span>, <span class="hljs-string">&#x27;attributes&#x27;</span>, <span class="hljs-string">&#x27;content&#x27;</span>]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @content?.base.jsx = <span class="hljs-literal">yes</span>
    fragments = [@makeCode(<span class="hljs-string">&#x27;&lt;&#x27;</span>)]
    fragments.push (tag = @tagName.compileToFragments(o, LEVEL_ACCESS))...
    fragments.push @attributes.compileToFragments(o)...
    <span class="hljs-keyword">if</span> @content
      fragments.push @makeCode(<span class="hljs-string">&#x27;&gt;&#x27;</span>)
      fragments.push @content.compileNode(o, LEVEL_LIST)...
      fragments.push [@makeCode(<span class="hljs-string">&#x27;&lt;/&#x27;</span>), tag..., @makeCode(<span class="hljs-string">&#x27;&gt;&#x27;</span>)]...
    <span class="hljs-keyword">else</span>
      fragments.push @makeCode(<span class="hljs-string">&#x27; /&gt;&#x27;</span>)
    fragments

  isFragment: <span class="hljs-function">-&gt;</span>
    !@tagName.base.value.length

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-136">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-136">&#x00a7;</a>
              </div>
              <p>The location data spanning the opening element &lt; … &gt; is captured by
the generated Arr which contains the element’s attributes</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @openingElementLocationData = jisonLocationDataToAstLocationData @attributes.locationData

    tagName = @tagName.base
    tagName.locationData = tagName.tagNameLocationData
    <span class="hljs-keyword">if</span> @content?
      @closingElementLocationData = mergeAstLocationData(
        jisonLocationDataToAstLocationData tagName.closingTagOpeningBracketLocationData
        jisonLocationDataToAstLocationData tagName.closingTagClosingBracketLocationData
      )

    super o

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isFragment()
      <span class="hljs-string">&#x27;JSXFragment&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;JSXElement&#x27;</span>

  elementAstProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
<span class="hljs-function">    <span class="hljs-title">tagNameAst</span> = =&gt;</span>
      tag = @tagName.unwrap()
      <span class="hljs-keyword">if</span> tag?.value <span class="hljs-keyword">and</span> <span class="hljs-string">&#x27;:&#x27;</span> <span class="hljs-keyword">in</span> tag.value
        tag = <span class="hljs-keyword">new</span> JSXNamespacedName tag
      tag.ast o

    openingElement = <span class="hljs-built_in">Object</span>.assign {
      type: <span class="hljs-string">&#x27;JSXOpeningElement&#x27;</span>
      name: tagNameAst()
      selfClosing: <span class="hljs-keyword">not</span> @closingElementLocationData?
      attributes: @attributes.ast o
    }, @openingElementLocationData

    closingElement = <span class="hljs-literal">null</span>
    <span class="hljs-keyword">if</span> @closingElementLocationData?
      closingElement = <span class="hljs-built_in">Object</span>.assign {
        type: <span class="hljs-string">&#x27;JSXClosingElement&#x27;</span>
        name: <span class="hljs-built_in">Object</span>.assign(
          tagNameAst(),
          jisonLocationDataToAstLocationData @tagName.base.closingTagNameLocationData
        )
      }, @closingElementLocationData
      <span class="hljs-keyword">if</span> closingElement.name.type <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;JSXMemberExpression&#x27;</span>, <span class="hljs-string">&#x27;JSXNamespacedName&#x27;</span>]
        rangeDiff = closingElement.range[<span class="hljs-number">0</span>] - openingElement.range[<span class="hljs-number">0</span>] + <span class="hljs-string">&#x27;/&#x27;</span>.length
        columnDiff = closingElement.loc.start.column - openingElement.loc.start.column + <span class="hljs-string">&#x27;/&#x27;</span>.length
<span class="hljs-function">        <span class="hljs-title">shiftAstLocationData</span> = <span class="hljs-params">(node)</span> =&gt;</span>
          node.range = [
            node.range[<span class="hljs-number">0</span>] + rangeDiff
            node.range[<span class="hljs-number">1</span>] + rangeDiff
          ]
          node.start += rangeDiff
          node.end += rangeDiff
          node.loc.start =
            line: @closingElementLocationData.loc.start.line
            column: node.loc.start.column + columnDiff
          node.loc.end =
            line: @closingElementLocationData.loc.start.line
            column: node.loc.end.column + columnDiff
        <span class="hljs-keyword">if</span> closingElement.name.type <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;JSXMemberExpression&#x27;</span>
          currentExpr = closingElement.name
          <span class="hljs-keyword">while</span> currentExpr.type <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;JSXMemberExpression&#x27;</span>
            shiftAstLocationData currentExpr <span class="hljs-keyword">unless</span> currentExpr <span class="hljs-keyword">is</span> closingElement.name
            shiftAstLocationData currentExpr.property
            currentExpr = currentExpr.object
          shiftAstLocationData currentExpr
        <span class="hljs-keyword">else</span> <span class="hljs-comment"># JSXNamespacedName</span>
          shiftAstLocationData closingElement.name.namespace
          shiftAstLocationData closingElement.name.name

    {openingElement, closingElement}

  fragmentAstProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    openingFragment = <span class="hljs-built_in">Object</span>.assign {
      type: <span class="hljs-string">&#x27;JSXOpeningFragment&#x27;</span>
    }, @openingElementLocationData

    closingFragment = <span class="hljs-built_in">Object</span>.assign {
      type: <span class="hljs-string">&#x27;JSXClosingFragment&#x27;</span>
    }, @closingElementLocationData

    {openingFragment, closingFragment}

  contentAst: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> [] <span class="hljs-keyword">unless</span> @content <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @content.base.isEmpty?()

    content = @content.unwrapAll()
    children =
      <span class="hljs-keyword">if</span> content <span class="hljs-keyword">instanceof</span> StringLiteral
        [<span class="hljs-keyword">new</span> JSXText content]
      <span class="hljs-keyword">else</span> <span class="hljs-comment"># StringWithInterpolations</span>
        <span class="hljs-keyword">for</span> element <span class="hljs-keyword">in</span> @content.unwrapAll().extractElements o, includeInterpolationWrappers: <span class="hljs-literal">yes</span>, isJsx: <span class="hljs-literal">yes</span>
          <span class="hljs-keyword">if</span> element <span class="hljs-keyword">instanceof</span> StringLiteral
            <span class="hljs-keyword">new</span> JSXText element
          <span class="hljs-keyword">else</span> <span class="hljs-comment"># Interpolation</span>
            {expression} = element
            <span class="hljs-keyword">unless</span> expression?
              emptyExpression = <span class="hljs-keyword">new</span> JSXEmptyExpression()
              emptyExpression.locationData = emptyExpressionLocationData {
                interpolationNode: element
                openingBrace: <span class="hljs-string">&#x27;{&#x27;</span>
                closingBrace: <span class="hljs-string">&#x27;}&#x27;</span>
              }

              <span class="hljs-keyword">new</span> JSXExpressionContainer emptyExpression, locationData: element.locationData
            <span class="hljs-keyword">else</span>
              unwrapped = expression.unwrapAll()
              <span class="hljs-keyword">if</span> unwrapped <span class="hljs-keyword">instanceof</span> JSXElement <span class="hljs-keyword">and</span></pre></div></div>
            
        </li>
        
        
        <li id="section-137">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-137">&#x00a7;</a>
              </div>
              <p>distinguish <code>&lt;a&gt;&lt;b /&gt;&lt;/a&gt;</code> from <code>&lt;a&gt;{&lt;b /&gt;}&lt;/a&gt;</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                  unwrapped.locationData.range[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> element.locationData.range[<span class="hljs-number">0</span>]
                unwrapped
              <span class="hljs-keyword">else</span>
                <span class="hljs-keyword">new</span> JSXExpressionContainer unwrapped, locationData: element.locationData

    child.ast(o) <span class="hljs-keyword">for</span> child <span class="hljs-keyword">in</span> children <span class="hljs-keyword">when</span> <span class="hljs-keyword">not</span> (child <span class="hljs-keyword">instanceof</span> JSXText <span class="hljs-keyword">and</span> child.value.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>)

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-built_in">Object</span>.assign(
      <span class="hljs-keyword">if</span> @isFragment()
        @fragmentAstProperties o
      <span class="hljs-keyword">else</span>
        @elementAstProperties o
    ,
      children: @contentAst o
    )

  astLocationData: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @closingElementLocationData?
      mergeAstLocationData @openingElementLocationData, @closingElementLocationData
    <span class="hljs-keyword">else</span>
      @openingElementLocationData</pre></div></div>
            
        </li>
        
        
        <li id="section-138">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-138">&#x00a7;</a>
              </div>
              <h3 id="call">Call</h3>

            </div>
            
        </li>
        
        
        <li id="section-139">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-139">&#x00a7;</a>
              </div>
              <p>Node for a function invocation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Call = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Call</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@variable, @args = [], @soak, @token)</span> -&gt;</span>
    super()

    @implicit = @args.implicit
    @isNew = <span class="hljs-literal">no</span>
    <span class="hljs-keyword">if</span> @variable <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> @variable.isNotCallable()
      @variable.error <span class="hljs-string">&quot;literal is not a function&quot;</span>

    <span class="hljs-keyword">if</span> @variable.base <span class="hljs-keyword">instanceof</span> JSXTag
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> JSXElement(
        tagName: @variable
        attributes: <span class="hljs-keyword">new</span> JSXAttributes @args[<span class="hljs-number">0</span>].base
        content: @args[<span class="hljs-number">1</span>]
      )</pre></div></div>
            
        </li>
        
        
        <li id="section-140">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-140">&#x00a7;</a>
              </div>
              <p><code>@variable</code> never gets output as a result of this node getting created as
part of <code>RegexWithInterpolations</code>, so for that case move any comments to
the <code>args</code> property that gets passed into <code>RegexWithInterpolations</code> via
the grammar.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @variable.base?.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;RegExp&#x27;</span> <span class="hljs-keyword">and</span> @args.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
      moveComments @variable, @args[<span class="hljs-number">0</span>]

  children: [<span class="hljs-string">&#x27;variable&#x27;</span>, <span class="hljs-string">&#x27;args&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-141">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-141">&#x00a7;</a>
              </div>
              <p>When setting the location, we sometimes need to update the start location to
account for a newly-discovered <code>new</code> operator to the left of us. This
expands the range on the left, but not the right.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  updateLocationDataIfMissing: <span class="hljs-function"><span class="hljs-params">(locationData)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @locationData <span class="hljs-keyword">and</span> @needsUpdatedStartLocation
      @locationData = <span class="hljs-built_in">Object</span>.assign {},
        @locationData,
        first_line: locationData.first_line
        first_column: locationData.first_column
        range: [
          locationData.range[<span class="hljs-number">0</span>]
          @locationData.range[<span class="hljs-number">1</span>]
        ]
      base = @variable?.base <span class="hljs-keyword">or</span> @variable
      <span class="hljs-keyword">if</span> base.needsUpdatedStartLocation
        @variable.locationData = <span class="hljs-built_in">Object</span>.assign {},
          @variable.locationData,
          first_line: locationData.first_line
          first_column: locationData.first_column
          range: [
            locationData.range[<span class="hljs-number">0</span>]
            @variable.locationData.range[<span class="hljs-number">1</span>]
          ]
        base.updateLocationDataIfMissing locationData
      <span class="hljs-keyword">delete</span> @needsUpdatedStartLocation
    super locationData</pre></div></div>
            
        </li>
        
        
        <li id="section-142">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-142">&#x00a7;</a>
              </div>
              <p>Tag this invocation as creating a new instance.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  newInstance: <span class="hljs-function">-&gt;</span>
    base = @variable?.base <span class="hljs-keyword">or</span> @variable
    <span class="hljs-keyword">if</span> base <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> base.isNew
      base.newInstance()
    <span class="hljs-keyword">else</span>
      @isNew = <span class="hljs-literal">true</span>
    @needsUpdatedStartLocation = <span class="hljs-literal">true</span>
    this</pre></div></div>
            
        </li>
        
        
        <li id="section-143">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-143">&#x00a7;</a>
              </div>
              <p>Soaked chained invocations unfold into if/else ternary structures.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  unfoldSoak: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @soak
      <span class="hljs-keyword">if</span> @variable <span class="hljs-keyword">instanceof</span> Super
        left = <span class="hljs-keyword">new</span> Literal @variable.compile o
        rite = <span class="hljs-keyword">new</span> Value left
        @variable.error <span class="hljs-string">&quot;Unsupported reference to &#x27;super&#x27;&quot;</span> <span class="hljs-keyword">unless</span> @variable.accessor?
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">return</span> ifn <span class="hljs-keyword">if</span> ifn = unfoldSoak o, this, <span class="hljs-string">&#x27;variable&#x27;</span>
        [left, rite] = <span class="hljs-keyword">new</span> Value(@variable).cacheReference o
      rite = <span class="hljs-keyword">new</span> Call rite, @args
      rite.isNew = @isNew
      left = <span class="hljs-keyword">new</span> Literal <span class="hljs-string">&quot;typeof <span class="hljs-subst">#{ left.compile o }</span> === \&quot;function\&quot;&quot;</span>
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> If left, <span class="hljs-keyword">new</span> Value(rite), soak: <span class="hljs-literal">yes</span>
    call = this
    list = []
    <span class="hljs-keyword">loop</span>
      <span class="hljs-keyword">if</span> call.variable <span class="hljs-keyword">instanceof</span> Call
        list.push call
        call = call.variable
        <span class="hljs-keyword">continue</span>
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> call.variable <span class="hljs-keyword">instanceof</span> Value
      list.push call
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> (call = call.variable.base) <span class="hljs-keyword">instanceof</span> Call
    <span class="hljs-keyword">for</span> call <span class="hljs-keyword">in</span> list.reverse()
      <span class="hljs-keyword">if</span> ifn
        <span class="hljs-keyword">if</span> call.variable <span class="hljs-keyword">instanceof</span> Call
          call.variable = ifn
        <span class="hljs-keyword">else</span>
          call.variable.base = ifn
      ifn = unfoldSoak o, call, <span class="hljs-string">&#x27;variable&#x27;</span>
    ifn</pre></div></div>
            
        </li>
        
        
        <li id="section-144">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-144">&#x00a7;</a>
              </div>
              <p>Compile a vanilla function call.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkForNewSuper()
    @variable?.front = @front
    compiledArgs = []</pre></div></div>
            
        </li>
        
        
        <li id="section-145">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-145">&#x00a7;</a>
              </div>
              <p>If variable is <code>Accessor</code> fragments are cached and used later
in <code>Value::compileNode</code> to ensure correct order of the compilation,
and reuse of variables in the scope.
Example:
<code>a(x = 5).b(-&gt; x = 6)</code> should compile in the same order as
<code>a(x = 5); b(-&gt; x = 6)</code>
(see issue #4437, <a href="https://github.com/jashkenas/coffeescript/issues/4437">https://github.com/jashkenas/coffeescript/issues/4437</a>)</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    varAccess = @variable?.properties?[<span class="hljs-number">0</span>] <span class="hljs-keyword">instanceof</span> Access
    argCode = (arg <span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> (@args || []) <span class="hljs-keyword">when</span> arg <span class="hljs-keyword">instanceof</span> Code)
    <span class="hljs-keyword">if</span> argCode.length &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> varAccess <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @variable.base.cached
      [cache] = @variable.base.cache o, LEVEL_ACCESS, <span class="hljs-function">-&gt;</span> <span class="hljs-literal">no</span>
      @variable.base.cached = cache

    <span class="hljs-keyword">for</span> arg, argIndex <span class="hljs-keyword">in</span> @args
      <span class="hljs-keyword">if</span> argIndex <span class="hljs-keyword">then</span> compiledArgs.push @makeCode <span class="hljs-string">&quot;, &quot;</span>
      compiledArgs.push (arg.compileToFragments o, LEVEL_LIST)...

    fragments = []
    <span class="hljs-keyword">if</span> @isNew
      fragments.push @makeCode <span class="hljs-string">&#x27;new &#x27;</span>
    fragments.push @variable.compileToFragments(o, LEVEL_ACCESS)...
    fragments.push @makeCode(<span class="hljs-string">&#x27;(&#x27;</span>), compiledArgs..., @makeCode(<span class="hljs-string">&#x27;)&#x27;</span>)
    fragments

  checkForNewSuper: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isNew
      @variable.error <span class="hljs-string">&quot;Unsupported reference to &#x27;super&#x27;&quot;</span> <span class="hljs-keyword">if</span> @variable <span class="hljs-keyword">instanceof</span> Super

  containsSoak: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @soak
    <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @variable?.containsSoak?()
    <span class="hljs-literal">no</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @soak <span class="hljs-keyword">and</span> @variable <span class="hljs-keyword">instanceof</span> Super <span class="hljs-keyword">and</span> o.scope.namedMethod()?.ctor
      @variable.error <span class="hljs-string">&quot;Unsupported reference to &#x27;super&#x27;&quot;</span>
    @checkForNewSuper()
    super o

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isNew
      <span class="hljs-string">&#x27;NewExpression&#x27;</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @containsSoak()
      <span class="hljs-string">&#x27;OptionalCallExpression&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;CallExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      callee: @variable.ast o, LEVEL_ACCESS
      arguments: arg.ast(o, LEVEL_LIST) <span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> @args
      optional: !!@soak
      implicit: !!@implicit</pre></div></div>
            
        </li>
        
        
        <li id="section-146">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-146">&#x00a7;</a>
              </div>
              <h3 id="super">Super</h3>

            </div>
            
        </li>
        
        
        <li id="section-147">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-147">&#x00a7;</a>
              </div>
              <p>Takes care of converting <code>super()</code> calls into calls against the prototype’s
function of the same name.
When <code>expressions</code> are set the call will be compiled in such a way that the
expressions are evaluated without altering the return value of the <code>SuperCall</code>
expression.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.SuperCall = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SuperCall</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Call</span></span>
  children: Call::children.concat [<span class="hljs-string">&#x27;expressions&#x27;</span>]

  isStatement: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @expressions?.length <span class="hljs-keyword">and</span> o.level <span class="hljs-keyword">is</span> LEVEL_TOP

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> super o <span class="hljs-keyword">unless</span> @expressions?.length

    superCall   = <span class="hljs-keyword">new</span> Literal fragmentsToText super o
    replacement = <span class="hljs-keyword">new</span> Block @expressions.slice()

    <span class="hljs-keyword">if</span> o.level &gt; LEVEL_TOP</pre></div></div>
            
        </li>
        
        
        <li id="section-148">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-148">&#x00a7;</a>
              </div>
              <p>If we might be in an expression we need to cache and return the result</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      [superCall, ref] = superCall.cache o, <span class="hljs-literal">null</span>, YES
      replacement.push ref

    replacement.unshift superCall
    replacement.compileToFragments o, <span class="hljs-keyword">if</span> o.level <span class="hljs-keyword">is</span> LEVEL_TOP <span class="hljs-keyword">then</span> o.level <span class="hljs-keyword">else</span> LEVEL_LIST

<span class="hljs-built_in">exports</span>.Super = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Super</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@accessor, @superLiteral)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;accessor&#x27;</span>]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkInInstanceMethod o

    method = o.scope.namedMethod()
    <span class="hljs-keyword">unless</span> method.ctor? <span class="hljs-keyword">or</span> @accessor?
      {name, variable} = method
      <span class="hljs-keyword">if</span> name.shouldCache() <span class="hljs-keyword">or</span> (name <span class="hljs-keyword">instanceof</span> Index <span class="hljs-keyword">and</span> name.index.isAssignable())
        nref = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.parent.freeVariable <span class="hljs-string">&#x27;name&#x27;</span>
        name.index = <span class="hljs-keyword">new</span> Assign nref, name.index
      @accessor = <span class="hljs-keyword">if</span> nref? <span class="hljs-keyword">then</span> <span class="hljs-keyword">new</span> Index nref <span class="hljs-keyword">else</span> name

    <span class="hljs-keyword">if</span> @accessor?.name?.comments</pre></div></div>
            
        </li>
        
        
        <li id="section-149">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-149">&#x00a7;</a>
              </div>
              <p>A <code>super()</code> call gets compiled to e.g. <code>super.method()</code>, which means
the <code>method</code> property name gets compiled for the first time here, and
again when the <code>method:</code> property of the class gets compiled. Since
this compilation happens first, comments attached to <code>method:</code> would
get incorrectly output near <code>super.method()</code>, when we want them to
get output on the second pass when <code>method:</code> is output. So set them
aside during this compilation pass, and put them back on the object so
that they’re there for the later compilation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      salvagedComments = @accessor.name.comments
      <span class="hljs-keyword">delete</span> @accessor.name.comments
    fragments = (<span class="hljs-keyword">new</span> Value (<span class="hljs-keyword">new</span> Literal <span class="hljs-string">&#x27;super&#x27;</span>), <span class="hljs-keyword">if</span> @accessor <span class="hljs-keyword">then</span> [ @accessor ] <span class="hljs-keyword">else</span> [])
    .compileToFragments o
    attachCommentsToNode salvagedComments, @accessor.name <span class="hljs-keyword">if</span> salvagedComments
    fragments

  checkInInstanceMethod: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    method = o.scope.namedMethod()
    @error <span class="hljs-string">&#x27;cannot use super outside of an instance method&#x27;</span> <span class="hljs-keyword">unless</span> method?.isMethod

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkInInstanceMethod o

    <span class="hljs-keyword">if</span> @accessor?
      <span class="hljs-keyword">return</span> (
        <span class="hljs-keyword">new</span> Value(
          <span class="hljs-keyword">new</span> Super().withLocationDataFrom (@superLiteral ? @)
          [@accessor]
        ).withLocationDataFrom @
      ).ast o

    super o</pre></div></div>
            
        </li>
        
        
        <li id="section-150">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-150">&#x00a7;</a>
              </div>
              <h3 id="regexwithinterpolations">RegexWithInterpolations</h3>

            </div>
            
        </li>
        
        
        <li id="section-151">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-151">&#x00a7;</a>
              </div>
              <p>Regexes with interpolations are in fact just a variation of a <code>Call</code> (a
<code>RegExp()</code> call to be precise) with a <code>StringWithInterpolations</code> inside.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.RegexWithInterpolations = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RegexWithInterpolations</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@call, {@heregexCommentTokens = []} = {})</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;call&#x27;</span>]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @call.compileNode o

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;InterpolatedRegExpLiteral&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    interpolatedPattern: @call.args[<span class="hljs-number">0</span>].ast o
    flags: @call.args[<span class="hljs-number">1</span>]?.unwrap().originalValue ? <span class="hljs-string">&#x27;&#x27;</span>
    comments:
      <span class="hljs-keyword">for</span> heregexCommentToken <span class="hljs-keyword">in</span> @heregexCommentTokens
        <span class="hljs-keyword">if</span> heregexCommentToken.here
          <span class="hljs-keyword">new</span> HereComment(heregexCommentToken).ast o
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">new</span> LineComment(heregexCommentToken).ast o</pre></div></div>
            
        </li>
        
        
        <li id="section-152">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-152">&#x00a7;</a>
              </div>
              <h3 id="taggedtemplatecall">TaggedTemplateCall</h3>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-built_in">exports</span>.TaggedTemplateCall = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaggedTemplateCall</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Call</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(variable, arg, soak)</span> -&gt;</span>
    arg = StringWithInterpolations.fromStringLiteral arg <span class="hljs-keyword">if</span> arg <span class="hljs-keyword">instanceof</span> StringLiteral
    super variable, [ arg ], soak

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @variable.compileToFragments(o, LEVEL_ACCESS).concat @args[<span class="hljs-number">0</span>].compileToFragments(o, LEVEL_LIST)

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;TaggedTemplateExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      tag: @variable.ast o, LEVEL_ACCESS
      quasi: @args[<span class="hljs-number">0</span>].ast o, LEVEL_LIST</pre></div></div>
            
        </li>
        
        
        <li id="section-153">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-153">&#x00a7;</a>
              </div>
              <h3 id="extends">Extends</h3>

            </div>
            
        </li>
        
        
        <li id="section-154">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-154">&#x00a7;</a>
              </div>
              <p>Node to extend an object’s prototype with an ancestor object.
After <code>goog.inherits</code> from the
<a href="https://github.com/google/closure-library/blob/master/closure/goog/base.js">Closure Library</a>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Extends = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Extends</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@child, @parent)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;child&#x27;</span>, <span class="hljs-string">&#x27;parent&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-155">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-155">&#x00a7;</a>
              </div>
              <p>Hooks one constructor into another’s prototype chain.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileToFragments: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">new</span> Call(<span class="hljs-keyword">new</span> Value(<span class="hljs-keyword">new</span> Literal utility <span class="hljs-string">&#x27;extend&#x27;</span>, o), [@child, @parent]).compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-156">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-156">&#x00a7;</a>
              </div>
              <h3 id="access">Access</h3>

            </div>
            
        </li>
        
        
        <li id="section-157">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-157">&#x00a7;</a>
              </div>
              <p>A <code>.</code> access into a property of a value, or the <code>::</code> shorthand for
an access into the object’s prototype.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Access = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Access</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@name, {@soak, @shorthand} = {})</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;name&#x27;</span>]

  compileToFragments: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    name = @name.compileToFragments o
    node = @name.unwrap()
    <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> PropertyName
      [@makeCode(<span class="hljs-string">&#x27;.&#x27;</span>), name...]
    <span class="hljs-keyword">else</span>
      [@makeCode(<span class="hljs-string">&#x27;[&#x27;</span>), name..., @makeCode(<span class="hljs-string">&#x27;]&#x27;</span>)]

  shouldCache: NO

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-158">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-158">&#x00a7;</a>
              </div>
              <p>Babel doesn’t have an AST node for <code>Access</code>, but rather just includes
this Access node’s child <code>name</code> Identifier node as the <code>property</code> of
the <code>MemberExpression</code> node.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @name.ast o</pre></div></div>
            
        </li>
        
        
        <li id="section-159">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-159">&#x00a7;</a>
              </div>
              <h3 id="index">Index</h3>

            </div>
            
        </li>
        
        
        <li id="section-160">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-160">&#x00a7;</a>
              </div>
              <p>A <code>[ ... ]</code> indexed access into an array or object.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Index = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Index</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@index)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;index&#x27;</span>]

  compileToFragments: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [].concat @makeCode(<span class="hljs-string">&quot;[&quot;</span>), @index.compileToFragments(o, LEVEL_PAREN), @makeCode(<span class="hljs-string">&quot;]&quot;</span>)

  shouldCache: <span class="hljs-function">-&gt;</span>
    @index.shouldCache()

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-161">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-161">&#x00a7;</a>
              </div>
              <p>Babel doesn’t have an AST node for <code>Index</code>, but rather just includes
this Index node’s child <code>index</code> Identifier node as the <code>property</code> of
the <code>MemberExpression</code> node. The fact that the <code>MemberExpression</code>’s
<code>property</code> is an Index means that <code>computed</code> is <code>true</code> for the
<code>MemberExpression</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @index.ast o</pre></div></div>
            
        </li>
        
        
        <li id="section-162">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-162">&#x00a7;</a>
              </div>
              <h3 id="range">Range</h3>

            </div>
            
        </li>
        
        
        <li id="section-163">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-163">&#x00a7;</a>
              </div>
              <p>A range literal. Ranges can be used to extract portions (slices) of arrays,
to specify a range for comprehensions, or as a value, to be expanded into the
corresponding array of integers at runtime.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Range = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Range</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

  children: [<span class="hljs-string">&#x27;from&#x27;</span>, <span class="hljs-string">&#x27;to&#x27;</span>]

  constructor: <span class="hljs-function"><span class="hljs-params">(@from, @to, tag)</span> -&gt;</span>
    super()

    @exclusive = tag <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;exclusive&#x27;</span>
    @equals = <span class="hljs-keyword">if</span> @exclusive <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;=&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-164">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-164">&#x00a7;</a>
              </div>
              <p>Compiles the range’s source variables – where it starts and where it ends.
But only if they need to be cached to avoid double evaluation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileVariables: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o = merge o, top: <span class="hljs-literal">true</span>
    shouldCache = del o, <span class="hljs-string">&#x27;shouldCache&#x27;</span>
    [@fromC, @fromVar] = @cacheToCodeFragments @from.cache o, LEVEL_LIST, shouldCache
    [@toC, @toVar]     = @cacheToCodeFragments @to.cache o, LEVEL_LIST, shouldCache
    [@step, @stepVar]  = @cacheToCodeFragments step.cache o, LEVEL_LIST, shouldCache <span class="hljs-keyword">if</span> step = del o, <span class="hljs-string">&#x27;step&#x27;</span>
    @fromNum = <span class="hljs-keyword">if</span> @from.isNumber() <span class="hljs-keyword">then</span> parseNumber @fromVar <span class="hljs-keyword">else</span> <span class="hljs-literal">null</span>
    @toNum   = <span class="hljs-keyword">if</span> @to.isNumber()   <span class="hljs-keyword">then</span> parseNumber @toVar   <span class="hljs-keyword">else</span> <span class="hljs-literal">null</span>
    @stepNum = <span class="hljs-keyword">if</span> step?.isNumber() <span class="hljs-keyword">then</span> parseNumber @stepVar <span class="hljs-keyword">else</span> <span class="hljs-literal">null</span></pre></div></div>
            
        </li>
        
        
        <li id="section-165">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-165">&#x00a7;</a>
              </div>
              <p>When compiled normally, the range returns the contents of the <em>for loop</em>
needed to iterate over the values in the range. Used by comprehensions.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @compileVariables o <span class="hljs-keyword">unless</span> @fromVar
    <span class="hljs-keyword">return</span> @compileArray(o) <span class="hljs-keyword">unless</span> o.index</pre></div></div>
            
        </li>
        
        
        <li id="section-166">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-166">&#x00a7;</a>
              </div>
              <p>Set up endpoints.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    known    = @fromNum? <span class="hljs-keyword">and</span> @toNum?
    idx      = del o, <span class="hljs-string">&#x27;index&#x27;</span>
    idxName  = del o, <span class="hljs-string">&#x27;name&#x27;</span>
    namedIndex = idxName <span class="hljs-keyword">and</span> idxName <span class="hljs-keyword">isnt</span> idx
    varPart  =
      <span class="hljs-keyword">if</span> known <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> namedIndex
        <span class="hljs-string">&quot;var <span class="hljs-subst">#{idx}</span> = <span class="hljs-subst">#{@fromC}</span>&quot;</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-string">&quot;<span class="hljs-subst">#{idx}</span> = <span class="hljs-subst">#{@fromC}</span>&quot;</span>
    varPart += <span class="hljs-string">&quot;, <span class="hljs-subst">#{@toC}</span>&quot;</span> <span class="hljs-keyword">if</span> @toC <span class="hljs-keyword">isnt</span> @toVar
    varPart += <span class="hljs-string">&quot;, <span class="hljs-subst">#{@step}</span>&quot;</span> <span class="hljs-keyword">if</span> @step <span class="hljs-keyword">isnt</span> @stepVar
    [lt, gt] = [<span class="hljs-string">&quot;<span class="hljs-subst">#{idx}</span> &lt;<span class="hljs-subst">#{@equals}</span>&quot;</span>, <span class="hljs-string">&quot;<span class="hljs-subst">#{idx}</span> &gt;<span class="hljs-subst">#{@equals}</span>&quot;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-167">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-167">&#x00a7;</a>
              </div>
              <p>Generate the condition.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    [<span class="hljs-keyword">from</span>, to] = [@fromNum, @toNum]</pre></div></div>
            
        </li>
        
        
        <li id="section-168">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-168">&#x00a7;</a>
              </div>
              <p>Always check if the <code>step</code> isn’t zero to avoid the infinite loop.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    stepNotZero = <span class="hljs-string">&quot;<span class="hljs-subst">#{ @stepNum ? @stepVar }</span> !== 0&quot;</span>
    stepCond = <span class="hljs-string">&quot;<span class="hljs-subst">#{ @stepNum ? @stepVar }</span> &gt; 0&quot;</span>
    lowerBound = <span class="hljs-string">&quot;<span class="hljs-subst">#{lt}</span> <span class="hljs-subst">#{ <span class="hljs-keyword">if</span> known <span class="hljs-keyword">then</span> to <span class="hljs-keyword">else</span> @toVar }</span>&quot;</span>
    upperBound = <span class="hljs-string">&quot;<span class="hljs-subst">#{gt}</span> <span class="hljs-subst">#{ <span class="hljs-keyword">if</span> known <span class="hljs-keyword">then</span> to <span class="hljs-keyword">else</span> @toVar }</span>&quot;</span>
    condPart =
      <span class="hljs-keyword">if</span> @step?
        <span class="hljs-keyword">if</span> @stepNum? <span class="hljs-keyword">and</span> @stepNum <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
          <span class="hljs-keyword">if</span> @stepNum &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{lowerBound}</span>&quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{upperBound}</span>&quot;</span>
        <span class="hljs-keyword">else</span>
          <span class="hljs-string">&quot;<span class="hljs-subst">#{stepNotZero}</span> &amp;&amp; (<span class="hljs-subst">#{stepCond}</span> ? <span class="hljs-subst">#{lowerBound}</span> : <span class="hljs-subst">#{upperBound}</span>)&quot;</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> known
          <span class="hljs-string">&quot;<span class="hljs-subst">#{ <span class="hljs-keyword">if</span> <span class="hljs-keyword">from</span> &lt;= to <span class="hljs-keyword">then</span> lt <span class="hljs-keyword">else</span> gt }</span> <span class="hljs-subst">#{to}</span>&quot;</span>
        <span class="hljs-keyword">else</span>
          <span class="hljs-string">&quot;(<span class="hljs-subst">#{@fromVar}</span> &lt;= <span class="hljs-subst">#{@toVar}</span> ? <span class="hljs-subst">#{lowerBound}</span> : <span class="hljs-subst">#{upperBound}</span>)&quot;</span>

    cond = <span class="hljs-keyword">if</span> @stepVar <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{@stepVar}</span> &gt; 0&quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{@fromVar}</span> &lt;= <span class="hljs-subst">#{@toVar}</span>&quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-169">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-169">&#x00a7;</a>
              </div>
              <p>Generate the step.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    stepPart = <span class="hljs-keyword">if</span> @stepVar
      <span class="hljs-string">&quot;<span class="hljs-subst">#{idx}</span> += <span class="hljs-subst">#{@stepVar}</span>&quot;</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> known
      <span class="hljs-keyword">if</span> namedIndex
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">from</span> &lt;= to <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;++<span class="hljs-subst">#{idx}</span>&quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;--<span class="hljs-subst">#{idx}</span>&quot;</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">from</span> &lt;= to <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{idx}</span>++&quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{idx}</span>--&quot;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">if</span> namedIndex
        <span class="hljs-string">&quot;<span class="hljs-subst">#{cond}</span> ? ++<span class="hljs-subst">#{idx}</span> : --<span class="hljs-subst">#{idx}</span>&quot;</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-string">&quot;<span class="hljs-subst">#{cond}</span> ? <span class="hljs-subst">#{idx}</span>++ : <span class="hljs-subst">#{idx}</span>--&quot;</span>

    varPart  = <span class="hljs-string">&quot;<span class="hljs-subst">#{idxName}</span> = <span class="hljs-subst">#{varPart}</span>&quot;</span> <span class="hljs-keyword">if</span> namedIndex
    stepPart = <span class="hljs-string">&quot;<span class="hljs-subst">#{idxName}</span> = <span class="hljs-subst">#{stepPart}</span>&quot;</span> <span class="hljs-keyword">if</span> namedIndex</pre></div></div>
            
        </li>
        
        
        <li id="section-170">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-170">&#x00a7;</a>
              </div>
              <p>The final loop body.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    [@makeCode <span class="hljs-string">&quot;<span class="hljs-subst">#{varPart}</span>; <span class="hljs-subst">#{condPart}</span>; <span class="hljs-subst">#{stepPart}</span>&quot;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-171">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-171">&#x00a7;</a>
              </div>
              <p>When used as a value, expand the range into the equivalent array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileArray: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    known = @fromNum? <span class="hljs-keyword">and</span> @toNum?
    <span class="hljs-keyword">if</span> known <span class="hljs-keyword">and</span> <span class="hljs-built_in">Math</span>.abs(@fromNum - @toNum) &lt;= <span class="hljs-number">20</span>
      range = [@fromNum..@toNum]
      range.pop() <span class="hljs-keyword">if</span> @exclusive
      <span class="hljs-keyword">return</span> [@makeCode <span class="hljs-string">&quot;[<span class="hljs-subst">#{ range.join(<span class="hljs-string">&#x27;, &#x27;</span>) }</span>]&quot;</span>]
    idt    = @tab + TAB
    i      = o.scope.freeVariable <span class="hljs-string">&#x27;i&#x27;</span>, single: <span class="hljs-literal">true</span>, reserve: <span class="hljs-literal">no</span>
    result = o.scope.freeVariable <span class="hljs-string">&#x27;results&#x27;</span>, reserve: <span class="hljs-literal">no</span>
    pre    = <span class="hljs-string">&quot;\n<span class="hljs-subst">#{idt}</span>var <span class="hljs-subst">#{result}</span> = [];&quot;</span>
    <span class="hljs-keyword">if</span> known
      o.index = i
      body    = fragmentsToText @compileNode o
    <span class="hljs-keyword">else</span>
      vars    = <span class="hljs-string">&quot;<span class="hljs-subst">#{i}</span> = <span class="hljs-subst">#{@fromC}</span>&quot;</span> + <span class="hljs-keyword">if</span> @toC <span class="hljs-keyword">isnt</span> @toVar <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;, <span class="hljs-subst">#{@toC}</span>&quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>
      cond    = <span class="hljs-string">&quot;<span class="hljs-subst">#{@fromVar}</span> &lt;= <span class="hljs-subst">#{@toVar}</span>&quot;</span>
      body    = <span class="hljs-string">&quot;var <span class="hljs-subst">#{vars}</span>; <span class="hljs-subst">#{cond}</span> ? <span class="hljs-subst">#{i}</span> &lt;<span class="hljs-subst">#{@equals}</span> <span class="hljs-subst">#{@toVar}</span> : <span class="hljs-subst">#{i}</span> &gt;<span class="hljs-subst">#{@equals}</span> <span class="hljs-subst">#{@toVar}</span>; <span class="hljs-subst">#{cond}</span> ? <span class="hljs-subst">#{i}</span>++ : <span class="hljs-subst">#{i}</span>--&quot;</span>
    post   = <span class="hljs-string">&quot;{ <span class="hljs-subst">#{result}</span>.push(<span class="hljs-subst">#{i}</span>); }\n<span class="hljs-subst">#{idt}</span>return <span class="hljs-subst">#{result}</span>;\n<span class="hljs-subst">#{o.indent}</span>&quot;</span>
<span class="hljs-function">    <span class="hljs-title">hasArgs</span> = <span class="hljs-params">(node)</span> -&gt;</span> node?.contains isLiteralArguments
    args   = <span class="hljs-string">&#x27;, arguments&#x27;</span> <span class="hljs-keyword">if</span> hasArgs(@from) <span class="hljs-keyword">or</span> hasArgs(@to)
    [@makeCode <span class="hljs-string">&quot;(function() {<span class="hljs-subst">#{pre}</span>\n<span class="hljs-subst">#{idt}</span>for (<span class="hljs-subst">#{body}</span>)<span class="hljs-subst">#{post}</span>}).apply(this<span class="hljs-subst">#{args ? <span class="hljs-string">&#x27;&#x27;</span>}</span>)&quot;</span>]

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> {
      from: @from?.ast(o) ? <span class="hljs-literal">null</span>
      to: @to?.ast(o) ? <span class="hljs-literal">null</span>
      @exclusive
    }</pre></div></div>
            
        </li>
        
        
        <li id="section-172">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-172">&#x00a7;</a>
              </div>
              <h3 id="slice">Slice</h3>

            </div>
            
        </li>
        
        
        <li id="section-173">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-173">&#x00a7;</a>
              </div>
              <p>An array slice literal. Unlike JavaScript’s <code>Array#slice</code>, the second parameter
specifies the index of the end of the slice, just as the first parameter
is the index of the beginning.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Slice = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Slice</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

  children: [<span class="hljs-string">&#x27;range&#x27;</span>]

  constructor: <span class="hljs-function"><span class="hljs-params">(@range)</span> -&gt;</span>
    super()</pre></div></div>
            
        </li>
        
        
        <li id="section-174">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-174">&#x00a7;</a>
              </div>
              <p>We have to be careful when trying to slice through the end of the array,
<code>9e9</code> is used because not all implementations respect <code>undefined</code> or <code>1/0</code>.
<code>9e9</code> should be safe because <code>9e9</code> &gt; <code>2**32</code>, the max array length.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    {to, <span class="hljs-keyword">from</span>} = @range</pre></div></div>
            
        </li>
        
        
        <li id="section-175">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-175">&#x00a7;</a>
              </div>
              <p>Handle an expression in the property access, e.g. <code>a[!b in c..]</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> <span class="hljs-keyword">from</span>?.shouldCache()
      <span class="hljs-keyword">from</span> = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">from</span>
    <span class="hljs-keyword">if</span> to?.shouldCache()
      to = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Parens to
    fromCompiled = <span class="hljs-keyword">from</span>?.compileToFragments(o, LEVEL_PAREN) <span class="hljs-keyword">or</span> [@makeCode <span class="hljs-string">&#x27;0&#x27;</span>]
    <span class="hljs-keyword">if</span> to
      compiled     = to.compileToFragments o, LEVEL_PAREN
      compiledText = fragmentsToText compiled
      <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> (<span class="hljs-keyword">not</span> @range.exclusive <span class="hljs-keyword">and</span> +compiledText <span class="hljs-keyword">is</span> <span class="hljs-number">-1</span>)
        toStr = <span class="hljs-string">&#x27;, &#x27;</span> + <span class="hljs-keyword">if</span> @range.exclusive
          compiledText
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> to.isNumber()
          <span class="hljs-string">&quot;<span class="hljs-subst">#{+compiledText + <span class="hljs-number">1</span>}</span>&quot;</span>
        <span class="hljs-keyword">else</span>
          compiled = to.compileToFragments o, LEVEL_ACCESS
          <span class="hljs-string">&quot;+<span class="hljs-subst">#{fragmentsToText compiled}</span> + 1 || 9e9&quot;</span>
    [@makeCode <span class="hljs-string">&quot;.slice(<span class="hljs-subst">#{ fragmentsToText fromCompiled }</span><span class="hljs-subst">#{ toStr <span class="hljs-keyword">or</span> <span class="hljs-string">&#x27;&#x27;</span> }</span>)&quot;</span>]

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @range.ast o</pre></div></div>
            
        </li>
        
        
        <li id="section-176">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-176">&#x00a7;</a>
              </div>
              <h3 id="obj">Obj</h3>

            </div>
            
        </li>
        
        
        <li id="section-177">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-177">&#x00a7;</a>
              </div>
              <p>An object literal, nothing fancy.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Obj = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Obj</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(props, @generated = <span class="hljs-literal">no</span>)</span> -&gt;</span>
    super()

    @objects = @properties = props <span class="hljs-keyword">or</span> []

  children: [<span class="hljs-string">&#x27;properties&#x27;</span>]

  isAssignable: <span class="hljs-function"><span class="hljs-params">(opts)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> @properties</pre></div></div>
            
        </li>
        
        
        <li id="section-178">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-178">&#x00a7;</a>
              </div>
              <p>Check for reserved words.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      message = isUnassignable prop.unwrapAll().value
      prop.error message <span class="hljs-keyword">if</span> message

      prop = prop.value <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span>
        prop.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span> <span class="hljs-keyword">and</span>
        prop.value?.base <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Arr
      <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> prop.isAssignable opts
    <span class="hljs-literal">yes</span>

  shouldCache: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">not</span> @isAssignable()</pre></div></div>
            
        </li>
        
        
        <li id="section-179">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-179">&#x00a7;</a>
              </div>
              <p>Check if object contains splat.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  hasSplat: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> @properties <span class="hljs-keyword">when</span> prop <span class="hljs-keyword">instanceof</span> Splat
    <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-180">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-180">&#x00a7;</a>
              </div>
              <p>Move rest property to the end of the list.
<code>{a, rest..., b} = obj</code> -&gt; <code>{a, b, rest...} = obj</code>
<code>foo = ({a, rest..., b}) -&gt;</code> -&gt; <code>foo = {a, b, rest...}) -&gt;</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  reorderProperties: <span class="hljs-function">-&gt;</span>
    props = @properties
    splatProps = @getAndCheckSplatProps()
    splatProp = props.splice splatProps[<span class="hljs-number">0</span>], <span class="hljs-number">1</span>
    @objects = @properties = [].concat props, splatProp

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @reorderProperties() <span class="hljs-keyword">if</span> @hasSplat() <span class="hljs-keyword">and</span> @lhs
    props = @properties
    <span class="hljs-keyword">if</span> @generated
      <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> props <span class="hljs-keyword">when</span> node <span class="hljs-keyword">instanceof</span> Value
        node.error <span class="hljs-string">&#x27;cannot have an implicit value in an implicit object&#x27;</span>

    idt      = o.indent += TAB
    lastNode = @lastNode @properties</pre></div></div>
            
        </li>
        
        
        <li id="section-181">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-181">&#x00a7;</a>
              </div>
              <p>If this object is the left-hand side of an assignment, all its children
are too.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @propagateLhs()

    isCompact = <span class="hljs-literal">yes</span>
    <span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> @properties
      <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> prop.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span>
        isCompact = <span class="hljs-literal">no</span>

    answer = []
    answer.push @makeCode <span class="hljs-keyword">if</span> isCompact <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;\n&#x27;</span>
    <span class="hljs-keyword">for</span> prop, i <span class="hljs-keyword">in</span> props
      join = <span class="hljs-keyword">if</span> i <span class="hljs-keyword">is</span> props.length - <span class="hljs-number">1</span>
        <span class="hljs-string">&#x27;&#x27;</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> isCompact
        <span class="hljs-string">&#x27;, &#x27;</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">is</span> lastNode
        <span class="hljs-string">&#x27;\n&#x27;</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-string">&#x27;,\n&#x27;</span>
      indent = <span class="hljs-keyword">if</span> isCompact <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">else</span> idt

      key = <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> prop.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span>
        prop.variable
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Assign
        prop.operatorToken.error <span class="hljs-string">&quot;unexpected <span class="hljs-subst">#{prop.operatorToken.value}</span>&quot;</span> <span class="hljs-keyword">unless</span> @lhs
        prop.variable
      <span class="hljs-keyword">else</span>
        prop
      <span class="hljs-keyword">if</span> key <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> key.hasProperties()
        key.error <span class="hljs-string">&#x27;invalid object key&#x27;</span> <span class="hljs-keyword">if</span> prop.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span> <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> key.this
        key  = key.properties[<span class="hljs-number">0</span>].name
        prop = <span class="hljs-keyword">new</span> Assign key, prop, <span class="hljs-string">&#x27;object&#x27;</span>
      <span class="hljs-keyword">if</span> key <span class="hljs-keyword">is</span> prop
        <span class="hljs-keyword">if</span> prop.shouldCache()
          [key, value] = prop.base.cache o
          key  = <span class="hljs-keyword">new</span> PropertyName key.value <span class="hljs-keyword">if</span> key <span class="hljs-keyword">instanceof</span> IdentifierLiteral
          prop = <span class="hljs-keyword">new</span> Assign key, value, <span class="hljs-string">&#x27;object&#x27;</span>
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> key <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> key.base <span class="hljs-keyword">instanceof</span> ComputedPropertyName</pre></div></div>
            
        </li>
        
        
        <li id="section-182">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-182">&#x00a7;</a>
              </div>
              <p><code>{ [foo()] }</code> output as <code>{ [ref = foo()]: ref }</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          <span class="hljs-keyword">if</span> prop.base.value.shouldCache()
            [key, value] = prop.base.value.cache o
            key  = <span class="hljs-keyword">new</span> ComputedPropertyName key.value <span class="hljs-keyword">if</span> key <span class="hljs-keyword">instanceof</span> IdentifierLiteral
            prop = <span class="hljs-keyword">new</span> Assign key, value, <span class="hljs-string">&#x27;object&#x27;</span>
          <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-183">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-183">&#x00a7;</a>
              </div>
              <p><code>{ [expression] }</code> output as <code>{ [expression]: expression }</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            prop = <span class="hljs-keyword">new</span> Assign key, prop.base.value, <span class="hljs-string">&#x27;object&#x27;</span>
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> prop.bareLiteral?(IdentifierLiteral) <span class="hljs-keyword">and</span> prop <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Splat
          prop = <span class="hljs-keyword">new</span> Assign prop, prop, <span class="hljs-string">&#x27;object&#x27;</span>
      <span class="hljs-keyword">if</span> indent <span class="hljs-keyword">then</span> answer.push @makeCode indent
      answer.push prop.compileToFragments(o, LEVEL_TOP)...
      <span class="hljs-keyword">if</span> join <span class="hljs-keyword">then</span> answer.push @makeCode join
    answer.push @makeCode <span class="hljs-keyword">if</span> isCompact <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>&quot;</span>
    answer = @wrapInBraces answer
    <span class="hljs-keyword">if</span> @front <span class="hljs-keyword">then</span> @wrapInParentheses answer <span class="hljs-keyword">else</span> answer

  getAndCheckSplatProps: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> @hasSplat() <span class="hljs-keyword">and</span> @lhs
    props = @properties
    splatProps = (i <span class="hljs-keyword">for</span> prop, i <span class="hljs-keyword">in</span> props <span class="hljs-keyword">when</span> prop <span class="hljs-keyword">instanceof</span> Splat)
    props[splatProps[<span class="hljs-number">1</span>]].error <span class="hljs-string">&quot;multiple spread elements are disallowed&quot;</span> <span class="hljs-keyword">if</span> splatProps?.length &gt; <span class="hljs-number">1</span>
    splatProps

  assigns: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> @properties <span class="hljs-keyword">when</span> prop.assigns name <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>
    <span class="hljs-literal">no</span>

  eachName: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> @properties
      prop = prop.value <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> prop.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span>
      prop = prop.unwrapAll()
      prop.eachName iterator <span class="hljs-keyword">if</span> prop.eachName?</pre></div></div>
            
        </li>
        
        
        <li id="section-184">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-184">&#x00a7;</a>
              </div>
              <p>Convert “bare” properties to <code>ObjectProperty</code>s (or <code>Splat</code>s).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  expandProperty: <span class="hljs-function"><span class="hljs-params">(property)</span> -&gt;</span>
    {variable, context, operatorToken} = property
    key = <span class="hljs-keyword">if</span> property <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span>
      variable
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> property <span class="hljs-keyword">instanceof</span> Assign
      operatorToken.error <span class="hljs-string">&quot;unexpected <span class="hljs-subst">#{operatorToken.value}</span>&quot;</span> <span class="hljs-keyword">unless</span> @lhs
      variable
    <span class="hljs-keyword">else</span>
      property
    <span class="hljs-keyword">if</span> key <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> key.hasProperties()
      key.error <span class="hljs-string">&#x27;invalid object key&#x27;</span> <span class="hljs-keyword">unless</span> context <span class="hljs-keyword">isnt</span> <span class="hljs-string">&#x27;object&#x27;</span> <span class="hljs-keyword">and</span> key.this
      <span class="hljs-keyword">if</span> property <span class="hljs-keyword">instanceof</span> Assign
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ObjectProperty fromAssign: property
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ObjectProperty key: property
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ObjectProperty(fromAssign: property) <span class="hljs-keyword">unless</span> key <span class="hljs-keyword">is</span> property
    <span class="hljs-keyword">return</span> property <span class="hljs-keyword">if</span> property <span class="hljs-keyword">instanceof</span> Splat

    <span class="hljs-keyword">new</span> ObjectProperty key: property

  expandProperties: <span class="hljs-function">-&gt;</span>
    @expandProperty(property) <span class="hljs-keyword">for</span> property <span class="hljs-keyword">in</span> @properties

  propagateLhs: <span class="hljs-function"><span class="hljs-params">(setLhs)</span> -&gt;</span>
    @lhs = <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> setLhs
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> @lhs

    <span class="hljs-keyword">for</span> property <span class="hljs-keyword">in</span> @properties
      <span class="hljs-keyword">if</span> property <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> property.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span>
        {value} = property
        unwrappedValue = value.unwrapAll()
        <span class="hljs-keyword">if</span> unwrappedValue <span class="hljs-keyword">instanceof</span> Arr <span class="hljs-keyword">or</span> unwrappedValue <span class="hljs-keyword">instanceof</span> Obj
          unwrappedValue.propagateLhs <span class="hljs-literal">yes</span>
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> unwrappedValue <span class="hljs-keyword">instanceof</span> Assign
          unwrappedValue.nestedLhs = <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> property <span class="hljs-keyword">instanceof</span> Assign</pre></div></div>
            
        </li>
        
        
        <li id="section-185">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-185">&#x00a7;</a>
              </div>
              <p>Shorthand property with default, e.g. <code>{a = 1} = b</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        property.nestedLhs = <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> property <span class="hljs-keyword">instanceof</span> Splat
        property.propagateLhs <span class="hljs-literal">yes</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @getAndCheckSplatProps()
    super o

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @lhs
      <span class="hljs-string">&#x27;ObjectPattern&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;ObjectExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      implicit: !!@generated
      properties:
        property.ast(o) <span class="hljs-keyword">for</span> property <span class="hljs-keyword">in</span> @expandProperties()

<span class="hljs-built_in">exports</span>.ObjectProperty = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ObjectProperty</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">({key, fromAssign})</span> -&gt;</span>
    super()
    <span class="hljs-keyword">if</span> fromAssign
      {variable: @key, value, context} = fromAssign
      <span class="hljs-keyword">if</span> context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-186">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-186">&#x00a7;</a>
              </div>
              <p>All non-shorthand properties (i.e. includes <code>:</code>).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        @value = value
      <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-187">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-187">&#x00a7;</a>
              </div>
              <p>Left-hand-side shorthand with default e.g. <code>{a = 1} = b</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        @value = fromAssign
        @shorthand = <span class="hljs-literal">yes</span>
      @locationData = fromAssign.locationData
    <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-188">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-188">&#x00a7;</a>
              </div>
              <p>Shorthand without default e.g. <code>{a}</code> or <code>{@a}</code> or <code>{[a]}</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      @key = key
      @shorthand = <span class="hljs-literal">yes</span>
      @locationData = key.locationData

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    isComputedPropertyName = (@key <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> @key.base <span class="hljs-keyword">instanceof</span> ComputedPropertyName) <span class="hljs-keyword">or</span> @key.unwrap() <span class="hljs-keyword">instanceof</span> StringWithInterpolations
    keyAst = @key.ast o, LEVEL_LIST

    <span class="hljs-keyword">return</span>
      key:
        <span class="hljs-keyword">if</span> keyAst?.declaration
          <span class="hljs-built_in">Object</span>.assign {}, keyAst, declaration: <span class="hljs-literal">no</span>
        <span class="hljs-keyword">else</span>
          keyAst
      value: @value?.ast(o, LEVEL_LIST) ? keyAst
      shorthand: !!@shorthand
      computed: !!isComputedPropertyName
      method: <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-189">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-189">&#x00a7;</a>
              </div>
              <h3 id="arr">Arr</h3>

            </div>
            
        </li>
        
        
        <li id="section-190">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-190">&#x00a7;</a>
              </div>
              <p>An array literal.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Arr = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Arr</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(objs, @lhs = <span class="hljs-literal">no</span>)</span> -&gt;</span>
    super()
    @objects = objs <span class="hljs-keyword">or</span> []
    @propagateLhs()

  children: [<span class="hljs-string">&#x27;objects&#x27;</span>]

  hasElision: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> @objects <span class="hljs-keyword">when</span> obj <span class="hljs-keyword">instanceof</span> Elision
    <span class="hljs-literal">no</span>

  isAssignable: <span class="hljs-function"><span class="hljs-params">(opts)</span> -&gt;</span>
    {allowExpansion, allowNontrailingSplat, allowEmptyArray = <span class="hljs-literal">no</span>} = opts ? {}
    <span class="hljs-keyword">return</span> allowEmptyArray <span class="hljs-keyword">unless</span> @objects.length

    <span class="hljs-keyword">for</span> obj, i <span class="hljs-keyword">in</span> @objects
      <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> allowNontrailingSplat <span class="hljs-keyword">and</span> obj <span class="hljs-keyword">instanceof</span> Splat <span class="hljs-keyword">and</span> i + <span class="hljs-number">1</span> <span class="hljs-keyword">isnt</span> @objects.length
      <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> (allowExpansion <span class="hljs-keyword">and</span> obj <span class="hljs-keyword">instanceof</span> Expansion) <span class="hljs-keyword">or</span> (obj.isAssignable(opts) <span class="hljs-keyword">and</span> (<span class="hljs-keyword">not</span> obj.isAtomic <span class="hljs-keyword">or</span> obj.isAtomic()))
    <span class="hljs-literal">yes</span>

  shouldCache: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">not</span> @isAssignable()

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> [@makeCode <span class="hljs-string">&#x27;[]&#x27;</span>] <span class="hljs-keyword">unless</span> @objects.length
    o.indent += TAB
<span class="hljs-function">    <span class="hljs-title">fragmentIsElision</span> = <span class="hljs-params">([ fragment ])</span> -&gt;</span>
      fragment.type <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;Elision&#x27;</span> <span class="hljs-keyword">and</span> fragment.code.trim() <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;,&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-191">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-191">&#x00a7;</a>
              </div>
              <p>Detect if <code>Elision</code>s at the beginning of the array are processed (e.g. [, , , a]).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    passedElision = <span class="hljs-literal">no</span>

    answer = []
    <span class="hljs-keyword">for</span> obj, objIndex <span class="hljs-keyword">in</span> @objects
      unwrappedObj = obj.unwrapAll()</pre></div></div>
            
        </li>
        
        
        <li id="section-192">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-192">&#x00a7;</a>
              </div>
              <p>Let <code>compileCommentFragments</code> know to intersperse block comments
into the fragments created when compiling this array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> unwrappedObj.comments <span class="hljs-keyword">and</span>
         unwrappedObj.comments.filter(<span class="hljs-function"><span class="hljs-params">(comment)</span> -&gt;</span> <span class="hljs-keyword">not</span> comment.here).length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
        unwrappedObj.includeCommentFragments = YES

    compiledObjs = (obj.compileToFragments o, LEVEL_LIST <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> @objects)
    olen = compiledObjs.length</pre></div></div>
            
        </li>
        
        
        <li id="section-193">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-193">&#x00a7;</a>
              </div>
              <p>If <code>compiledObjs</code> includes newlines, we will output this as a multiline
array (i.e. with a newline and indentation after the <code>[</code>). If an element
contains line comments, that should also trigger multiline output since
by definition line comments will introduce newlines into our output.
The exception is if only the first element has line comments; in that
case, output as the compact form if we otherwise would have, so that the
first element’s line comments get output before or after the array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    includesLineCommentsOnNonFirstElement = <span class="hljs-literal">no</span>
    <span class="hljs-keyword">for</span> fragments, index <span class="hljs-keyword">in</span> compiledObjs
      <span class="hljs-keyword">for</span> fragment <span class="hljs-keyword">in</span> fragments
        <span class="hljs-keyword">if</span> fragment.isHereComment
          fragment.code = fragment.code.trim()
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> index <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> includesLineCommentsOnNonFirstElement <span class="hljs-keyword">is</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">and</span> hasLineComments fragment
          includesLineCommentsOnNonFirstElement = <span class="hljs-literal">yes</span></pre></div></div>
            
        </li>
        
        
        <li id="section-194">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-194">&#x00a7;</a>
              </div>
              <p>Add ‘, ‘ if all <code>Elisions</code> from the beginning of the array are processed (e.g. [, , , a]) and
element isn’t <code>Elision</code> or last element is <code>Elision</code> (e.g. [a,,b,,])</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> index <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> passedElision <span class="hljs-keyword">and</span> (<span class="hljs-keyword">not</span> fragmentIsElision(fragments) <span class="hljs-keyword">or</span> index <span class="hljs-keyword">is</span> olen - <span class="hljs-number">1</span>)
        answer.push @makeCode <span class="hljs-string">&#x27;, &#x27;</span>
      passedElision = passedElision <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> fragmentIsElision fragments
      answer.push fragments...
    <span class="hljs-keyword">if</span> includesLineCommentsOnNonFirstElement <span class="hljs-keyword">or</span> <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">in</span> fragmentsToText(answer)
      <span class="hljs-keyword">for</span> fragment, fragmentIndex <span class="hljs-keyword">in</span> answer
        <span class="hljs-keyword">if</span> fragment.isHereComment
          fragment.code = <span class="hljs-string">&quot;<span class="hljs-subst">#{multident(fragment.code, o.indent, <span class="hljs-literal">no</span>)}</span>\n<span class="hljs-subst">#{o.indent}</span>&quot;</span>
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> fragment.code <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;, &#x27;</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> fragment?.isElision <span class="hljs-keyword">and</span> fragment.type <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;StringLiteral&#x27;</span>, <span class="hljs-string">&#x27;StringWithInterpolations&#x27;</span>]
          fragment.code = <span class="hljs-string">&quot;,\n<span class="hljs-subst">#{o.indent}</span>&quot;</span>
      answer.unshift @makeCode <span class="hljs-string">&quot;[\n<span class="hljs-subst">#{o.indent}</span>&quot;</span>
      answer.push @makeCode <span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>]&quot;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">for</span> fragment <span class="hljs-keyword">in</span> answer <span class="hljs-keyword">when</span> fragment.isHereComment
        fragment.code = <span class="hljs-string">&quot;<span class="hljs-subst">#{fragment.code}</span> &quot;</span>
      answer.unshift @makeCode <span class="hljs-string">&#x27;[&#x27;</span>
      answer.push @makeCode <span class="hljs-string">&#x27;]&#x27;</span>
    answer

  assigns: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> @objects <span class="hljs-keyword">when</span> obj.assigns name <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>
    <span class="hljs-literal">no</span>

  eachName: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> @objects
      obj = obj.unwrapAll()
      obj.eachName iterator</pre></div></div>
            
        </li>
        
        
        <li id="section-195">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-195">&#x00a7;</a>
              </div>
              <p>If this array is the left-hand side of an assignment, all its children
are too.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  propagateLhs: <span class="hljs-function"><span class="hljs-params">(setLhs)</span> -&gt;</span>
    @lhs = <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> setLhs
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> @lhs
    <span class="hljs-keyword">for</span> object <span class="hljs-keyword">in</span> @objects
      object.lhs = <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> object <span class="hljs-keyword">instanceof</span> Splat <span class="hljs-keyword">or</span> object <span class="hljs-keyword">instanceof</span> Expansion
      unwrappedObject = object.unwrapAll()
      <span class="hljs-keyword">if</span> unwrappedObject <span class="hljs-keyword">instanceof</span> Arr <span class="hljs-keyword">or</span> unwrappedObject <span class="hljs-keyword">instanceof</span> Obj
        unwrappedObject.propagateLhs <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> unwrappedObject <span class="hljs-keyword">instanceof</span> Assign
        unwrappedObject.nestedLhs = <span class="hljs-literal">yes</span>

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @lhs
      <span class="hljs-string">&#x27;ArrayPattern&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;ArrayExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      elements:
        object.ast(o, LEVEL_LIST) <span class="hljs-keyword">for</span> object <span class="hljs-keyword">in</span> @objects</pre></div></div>
            
        </li>
        
        
        <li id="section-196">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-196">&#x00a7;</a>
              </div>
              <h3 id="class">Class</h3>

            </div>
            
        </li>
        
        
        <li id="section-197">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-197">&#x00a7;</a>
              </div>
              <p>The CoffeeScript class definition.
Initialize a <strong>Class</strong> with its name, an optional superclass, and a body.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-built_in">exports</span>.Class = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Class</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  children: [<span class="hljs-string">&#x27;variable&#x27;</span>, <span class="hljs-string">&#x27;parent&#x27;</span>, <span class="hljs-string">&#x27;body&#x27;</span>]

  constructor: <span class="hljs-function"><span class="hljs-params">(@variable, @parent, @body)</span> -&gt;</span>
    super()
    <span class="hljs-keyword">unless</span> @body?
      @body = <span class="hljs-keyword">new</span> Block
      @hasGeneratedBody = <span class="hljs-literal">yes</span>

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @name          = @determineName()
    executableBody = @walkBody o</pre></div></div>
            
        </li>
        
        
        <li id="section-198">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-198">&#x00a7;</a>
              </div>
              <p>Special handling to allow <code>class expr.A extends A</code> declarations</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    parentName    = @parent.base.value <span class="hljs-keyword">if</span> @parent <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @parent.hasProperties()
    @hasNameClash = @name? <span class="hljs-keyword">and</span> @name <span class="hljs-keyword">is</span> parentName

    node = @

    <span class="hljs-keyword">if</span> executableBody <span class="hljs-keyword">or</span> @hasNameClash
      node = <span class="hljs-keyword">new</span> ExecutableClassBody node, executableBody
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> @name? <span class="hljs-keyword">and</span> o.level <span class="hljs-keyword">is</span> LEVEL_TOP</pre></div></div>
            
        </li>
        
        
        <li id="section-199">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-199">&#x00a7;</a>
              </div>
              <p>Anonymous classes are only valid in expressions</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      node = <span class="hljs-keyword">new</span> Parens node

    <span class="hljs-keyword">if</span> @boundMethods.length <span class="hljs-keyword">and</span> @parent
      @variable ?= <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;_class&#x27;</span>
      [@variable, @variableRef] = @variable.cache o <span class="hljs-keyword">unless</span> @variableRef?

    <span class="hljs-keyword">if</span> @variable
      node = <span class="hljs-keyword">new</span> Assign @variable, node, <span class="hljs-literal">null</span>, { @moduleDeclaration }

    @compileNode = @compileClassDeclaration
    <span class="hljs-keyword">try</span>
      <span class="hljs-keyword">return</span> node.compileToFragments o
    <span class="hljs-keyword">finally</span>
      <span class="hljs-keyword">delete</span> @compileNode

  compileClassDeclaration: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @ctor ?= @makeDefaultConstructor() <span class="hljs-keyword">if</span> @externalCtor <span class="hljs-keyword">or</span> @boundMethods.length
    @ctor?.noReturn = <span class="hljs-literal">true</span>

    @proxyBoundMethods() <span class="hljs-keyword">if</span> @boundMethods.length

    o.indent += TAB

    result = []
    result.push @makeCode <span class="hljs-string">&quot;class &quot;</span>
    result.push @makeCode @name <span class="hljs-keyword">if</span> @name
    @compileCommentFragments o, @variable, result <span class="hljs-keyword">if</span> @variable?.comments?
    result.push @makeCode <span class="hljs-string">&#x27; &#x27;</span> <span class="hljs-keyword">if</span> @name
    result.push @makeCode(<span class="hljs-string">&#x27;extends &#x27;</span>), @parent.compileToFragments(o)..., @makeCode <span class="hljs-string">&#x27; &#x27;</span> <span class="hljs-keyword">if</span> @parent

    result.push @makeCode <span class="hljs-string">&#x27;{&#x27;</span>
    <span class="hljs-keyword">unless</span> @body.isEmpty()
      @body.spaced = <span class="hljs-literal">true</span>
      result.push @makeCode <span class="hljs-string">&#x27;\n&#x27;</span>
      result.push @body.compileToFragments(o, LEVEL_TOP)...
      result.push @makeCode <span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>&quot;</span>
    result.push @makeCode <span class="hljs-string">&#x27;}&#x27;</span>

    result</pre></div></div>
            
        </li>
        
        
        <li id="section-200">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-200">&#x00a7;</a>
              </div>
              <p>Figure out the appropriate name for this class</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  determineName: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span> <span class="hljs-keyword">unless</span> @variable
    [..., tail] = @variable.properties
    node = <span class="hljs-keyword">if</span> tail
      tail <span class="hljs-keyword">instanceof</span> Access <span class="hljs-keyword">and</span> tail.name
    <span class="hljs-keyword">else</span>
      @variable.base
    <span class="hljs-keyword">unless</span> node <span class="hljs-keyword">instanceof</span> IdentifierLiteral <span class="hljs-keyword">or</span> node <span class="hljs-keyword">instanceof</span> PropertyName
      <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>
    name = node.value
    <span class="hljs-keyword">unless</span> tail
      message = isUnassignable name
      @variable.error message <span class="hljs-keyword">if</span> message
    <span class="hljs-keyword">if</span> name <span class="hljs-keyword">in</span> JS_FORBIDDEN <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;_<span class="hljs-subst">#{name}</span>&quot;</span> <span class="hljs-keyword">else</span> name

  walkBody: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @ctor          = <span class="hljs-literal">null</span>
    @boundMethods  = []
    executableBody = <span class="hljs-literal">null</span>

    initializer     = []
    { expressions } = @body

    i = <span class="hljs-number">0</span>
    <span class="hljs-keyword">for</span> expression <span class="hljs-keyword">in</span> expressions.slice()
      <span class="hljs-keyword">if</span> expression <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> expression.isObject <span class="hljs-literal">true</span>
        { properties } = expression.base
        exprs     = []
        end       = <span class="hljs-number">0</span>
        start     = <span class="hljs-number">0</span>
<span class="hljs-function">        <span class="hljs-title">pushSlice</span> = -&gt;</span> exprs.push <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Obj properties[start...end], <span class="hljs-literal">true</span> <span class="hljs-keyword">if</span> end &gt; start

        <span class="hljs-keyword">while</span> assign = properties[end]
          <span class="hljs-keyword">if</span> initializerExpression = @addInitializerExpression assign, o
            pushSlice()
            exprs.push initializerExpression
            initializer.push initializerExpression
            start = end + <span class="hljs-number">1</span>
          end++
        pushSlice()

        expressions[i..i] = exprs
        i += exprs.length
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> initializerExpression = @addInitializerExpression expression, o
          initializer.push initializerExpression
          expressions[i] = initializerExpression
        i += <span class="hljs-number">1</span>

    <span class="hljs-keyword">for</span> method <span class="hljs-keyword">in</span> initializer <span class="hljs-keyword">when</span> method <span class="hljs-keyword">instanceof</span> Code
      <span class="hljs-keyword">if</span> method.ctor
        method.error <span class="hljs-string">&#x27;Cannot define more than one constructor in a class&#x27;</span> <span class="hljs-keyword">if</span> @ctor
        @ctor = method
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> method.isStatic <span class="hljs-keyword">and</span> method.bound
        method.context = @name
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> method.bound
        @boundMethods.push method

    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> o.compiling
    <span class="hljs-keyword">if</span> initializer.length <span class="hljs-keyword">isnt</span> expressions.length
      @body.expressions = (expression.hoist() <span class="hljs-keyword">for</span> expression <span class="hljs-keyword">in</span> initializer)
      <span class="hljs-keyword">new</span> Block expressions</pre></div></div>
            
        </li>
        
        
        <li id="section-201">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-201">&#x00a7;</a>
              </div>
              <p>Add an expression to the class initializer</p>
<p>This is the key method for determining whether an expression in a class
body should appear in the initializer or the executable body. If the given
<code>node</code> is valid in a class body the method will return a (new, modified,
or identical) node for inclusion in the class initializer, otherwise
nothing will be returned and the node will appear in the executable body.</p>
<p>At time of writing, only methods (instance and static) are valid in ES
class initializers. As new ES class features (such as class fields) reach
Stage 4, this method will need to be updated to support them. We
additionally allow <code>PassthroughLiteral</code>s (backticked expressions) in the
initializer as an escape hatch for ES features that are not implemented
(e.g. getters and setters defined via the <code>get</code> and <code>set</code> keywords as
opposed to the <code>Object.defineProperty</code> method).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  addInitializerExpression: <span class="hljs-function"><span class="hljs-params">(node, o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> node.unwrapAll() <span class="hljs-keyword">instanceof</span> PassthroughLiteral
      node
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @validInitializerMethod node
      @addInitializerMethod node
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> o.compiling <span class="hljs-keyword">and</span> @validClassProperty node
      @addClassProperty node
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> o.compiling <span class="hljs-keyword">and</span> @validClassPrototypeProperty node
      @addClassPrototypeProperty node
    <span class="hljs-keyword">else</span>
      <span class="hljs-literal">null</span></pre></div></div>
            
        </li>
        
        
        <li id="section-202">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-202">&#x00a7;</a>
              </div>
              <p>Checks if the given node is a valid ES class initializer method.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  validInitializerMethod: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> node <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> node.value <span class="hljs-keyword">instanceof</span> Code
    <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> node.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> node.variable.hasProperties()
    <span class="hljs-keyword">return</span> node.variable.looksStatic(@name) <span class="hljs-keyword">and</span> (@name <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> node.value.bound)</pre></div></div>
            
        </li>
        
        
        <li id="section-203">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-203">&#x00a7;</a>
              </div>
              <p>Returns a configured class initializer method</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  addInitializerMethod: <span class="hljs-function"><span class="hljs-params">(assign)</span> -&gt;</span>
    { variable, value: method, operatorToken } = assign
    method.isMethod = <span class="hljs-literal">yes</span>
    method.isStatic = variable.looksStatic @name

    <span class="hljs-keyword">if</span> method.isStatic
      method.name = variable.properties[<span class="hljs-number">0</span>]
    <span class="hljs-keyword">else</span>
      methodName  = variable.base
      method.name = <span class="hljs-keyword">new</span> (<span class="hljs-keyword">if</span> methodName.shouldCache() <span class="hljs-keyword">then</span> Index <span class="hljs-keyword">else</span> Access) methodName
      method.name.updateLocationDataIfMissing methodName.locationData
      isConstructor =
        <span class="hljs-keyword">if</span> methodName <span class="hljs-keyword">instanceof</span> StringLiteral
          methodName.originalValue <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;constructor&#x27;</span>
        <span class="hljs-keyword">else</span>
          methodName.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;constructor&#x27;</span>
      method.ctor = (<span class="hljs-keyword">if</span> @parent <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;derived&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;base&#x27;</span>) <span class="hljs-keyword">if</span> isConstructor
      method.error <span class="hljs-string">&#x27;Cannot define a constructor as a bound (fat arrow) function&#x27;</span> <span class="hljs-keyword">if</span> method.bound <span class="hljs-keyword">and</span> method.ctor

    method.operatorToken = operatorToken
    method

  validClassProperty: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> node <span class="hljs-keyword">instanceof</span> Assign
    <span class="hljs-keyword">return</span> node.variable.looksStatic @name

  addClassProperty: <span class="hljs-function"><span class="hljs-params">(assign)</span> -&gt;</span>
    {variable, value, operatorToken} = assign
    {staticClassName} = variable.looksStatic @name
    <span class="hljs-keyword">new</span> ClassProperty({
      name: variable.properties[<span class="hljs-number">0</span>]
      isStatic: <span class="hljs-literal">yes</span>
      staticClassName
      value
      operatorToken
    }).withLocationDataFrom assign

  validClassPrototypeProperty: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> node <span class="hljs-keyword">instanceof</span> Assign
    node.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> node.variable.hasProperties()

  addClassPrototypeProperty: <span class="hljs-function"><span class="hljs-params">(assign)</span> -&gt;</span>
    {variable, value} = assign
    <span class="hljs-keyword">new</span> ClassPrototypeProperty({
      name: variable.base
      value
    }).withLocationDataFrom assign

  makeDefaultConstructor: <span class="hljs-function">-&gt;</span>
    ctor = @addInitializerMethod <span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> PropertyName <span class="hljs-string">&#x27;constructor&#x27;</span>), <span class="hljs-keyword">new</span> Code
    @body.unshift ctor

    <span class="hljs-keyword">if</span> @parent
      ctor.body.push <span class="hljs-keyword">new</span> SuperCall <span class="hljs-keyword">new</span> Super, [<span class="hljs-keyword">new</span> Splat <span class="hljs-keyword">new</span> IdentifierLiteral <span class="hljs-string">&#x27;arguments&#x27;</span>]

    <span class="hljs-keyword">if</span> @externalCtor
      applyCtor = <span class="hljs-keyword">new</span> Value @externalCtor, [ <span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> PropertyName <span class="hljs-string">&#x27;apply&#x27;</span> ]
      applyArgs = [ <span class="hljs-keyword">new</span> ThisLiteral, <span class="hljs-keyword">new</span> IdentifierLiteral <span class="hljs-string">&#x27;arguments&#x27;</span> ]
      ctor.body.push <span class="hljs-keyword">new</span> Call applyCtor, applyArgs
      ctor.body.makeReturn()

    ctor

  proxyBoundMethods: <span class="hljs-function">-&gt;</span>
    @ctor.thisAssignments = <span class="hljs-keyword">for</span> method <span class="hljs-keyword">in</span> @boundMethods
      method.classVariable = @variableRef <span class="hljs-keyword">if</span> @parent

      name = <span class="hljs-keyword">new</span> Value(<span class="hljs-keyword">new</span> ThisLiteral, [ method.name ])
      <span class="hljs-keyword">new</span> Assign name, <span class="hljs-keyword">new</span> Call(<span class="hljs-keyword">new</span> Value(name, [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> PropertyName <span class="hljs-string">&#x27;bind&#x27;</span>]), [<span class="hljs-keyword">new</span> ThisLiteral])

    <span class="hljs-literal">null</span>

  declareName: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> (name = @variable?.unwrap()) <span class="hljs-keyword">instanceof</span> IdentifierLiteral
    alreadyDeclared = o.scope.find name.value
    name.isDeclaration = <span class="hljs-keyword">not</span> alreadyDeclared

  isStatementAst: <span class="hljs-function">-&gt;</span> <span class="hljs-literal">yes</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> jumpNode = @body.jumps()
      jumpNode.error <span class="hljs-string">&#x27;Class bodies cannot contain pure statements&#x27;</span>
    <span class="hljs-keyword">if</span> argumentsNode = @body.contains isLiteralArguments
      argumentsNode.error <span class="hljs-string">&quot;Class bodies shouldn&#x27;t reference arguments&quot;</span>
    @declareName o
    @name = @determineName()
    @body.isClassBody = <span class="hljs-literal">yes</span>
    @body.locationData = zeroWidthLocationDataFromEndLocation @locationData <span class="hljs-keyword">if</span> @hasGeneratedBody
    @walkBody o
    sniffDirectives @body.expressions
    @ctor?.noReturn = <span class="hljs-literal">yes</span>

    super o

  astType: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> o.level <span class="hljs-keyword">is</span> LEVEL_TOP
      <span class="hljs-string">&#x27;ClassDeclaration&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;ClassExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      id: @variable?.ast(o) ? <span class="hljs-literal">null</span>
      superClass: @parent?.ast(o, LEVEL_PAREN) ? <span class="hljs-literal">null</span>
      body: @body.ast o, LEVEL_TOP

<span class="hljs-built_in">exports</span>.ExecutableClassBody = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExecutableClassBody</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  children: [ <span class="hljs-string">&#x27;class&#x27;</span>, <span class="hljs-string">&#x27;body&#x27;</span> ]

  defaultClassVariableName: <span class="hljs-string">&#x27;_Class&#x27;</span>

  constructor: <span class="hljs-function"><span class="hljs-params">(@class, @body = <span class="hljs-keyword">new</span> Block)</span> -&gt;</span>
    super()

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> jumpNode = @body.jumps()
      jumpNode.error <span class="hljs-string">&#x27;Class bodies cannot contain pure statements&#x27;</span>
    <span class="hljs-keyword">if</span> argumentsNode = @body.contains isLiteralArguments
      argumentsNode.error <span class="hljs-string">&quot;Class bodies shouldn&#x27;t reference arguments&quot;</span>

    params  = []
    args    = [<span class="hljs-keyword">new</span> ThisLiteral]
    wrapper = <span class="hljs-keyword">new</span> Code params, @body
    klass   = <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Call (<span class="hljs-keyword">new</span> Value wrapper, [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> PropertyName <span class="hljs-string">&#x27;call&#x27;</span>]), args

    @body.spaced = <span class="hljs-literal">true</span>

    o.classScope = wrapper.makeScope o.scope

    @name      = @class.name ? o.classScope.freeVariable @defaultClassVariableName
    ident      = <span class="hljs-keyword">new</span> IdentifierLiteral @name
    directives = @walkBody()
    @setContext()

    <span class="hljs-keyword">if</span> @class.hasNameClash
      parent = <span class="hljs-keyword">new</span> IdentifierLiteral o.classScope.freeVariable <span class="hljs-string">&#x27;superClass&#x27;</span>
      wrapper.params.push <span class="hljs-keyword">new</span> Param parent
      args.push @class.parent
      @class.parent = parent

    <span class="hljs-keyword">if</span> @externalCtor
      externalCtor = <span class="hljs-keyword">new</span> IdentifierLiteral o.classScope.freeVariable <span class="hljs-string">&#x27;ctor&#x27;</span>, reserve: <span class="hljs-literal">no</span>
      @class.externalCtor = externalCtor
      @externalCtor.variable.base = externalCtor

    <span class="hljs-keyword">if</span> @name <span class="hljs-keyword">isnt</span> @class.name
      @body.expressions.unshift <span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> IdentifierLiteral @name), @class
    <span class="hljs-keyword">else</span>
      @body.expressions.unshift @class
    @body.expressions.unshift directives...
    @body.push ident

    klass.compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-204">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-204">&#x00a7;</a>
              </div>
              <p>Traverse the class’s children and:</p>
<ul>
<li>Hoist valid ES properties into <code>@properties</code></li>
<li>Hoist static assignments into <code>@properties</code></li>
<li>Convert invalid ES properties into class or prototype assignments</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  walkBody: <span class="hljs-function">-&gt;</span>
    directives  = []

    index = <span class="hljs-number">0</span>
    <span class="hljs-keyword">while</span> expr = @body.expressions[index]
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> expr <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> expr.isString()
      <span class="hljs-keyword">if</span> expr.hoisted
        index++
      <span class="hljs-keyword">else</span>
        directives.push @body.expressions.splice(index, <span class="hljs-number">1</span>)...

    @traverseChildren <span class="hljs-literal">false</span>, <span class="hljs-function"><span class="hljs-params">(child)</span> =&gt;</span>
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> <span class="hljs-keyword">if</span> child <span class="hljs-keyword">instanceof</span> Class <span class="hljs-keyword">or</span> child <span class="hljs-keyword">instanceof</span> HoistTarget

      cont = <span class="hljs-literal">true</span>
      <span class="hljs-keyword">if</span> child <span class="hljs-keyword">instanceof</span> Block
        <span class="hljs-keyword">for</span> node, i <span class="hljs-keyword">in</span> child.expressions
          <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> node.isObject(<span class="hljs-literal">true</span>)
            cont = <span class="hljs-literal">false</span>
            child.expressions[i] = @addProperties node.base.properties
          <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> node.variable.looksStatic @name
            node.value.isStatic = <span class="hljs-literal">yes</span>
        child.expressions = flatten child.expressions
      cont

    directives

  setContext: <span class="hljs-function">-&gt;</span>
    @body.traverseChildren <span class="hljs-literal">false</span>, <span class="hljs-function"><span class="hljs-params">(node)</span> =&gt;</span>
      <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> ThisLiteral
        node.value   = @name
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">and</span> node.bound <span class="hljs-keyword">and</span> (node.isStatic <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> node.name)
        node.context = @name</pre></div></div>
            
        </li>
        
        
        <li id="section-205">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-205">&#x00a7;</a>
              </div>
              <p>Make class/prototype assignments for invalid ES properties</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  addProperties: <span class="hljs-function"><span class="hljs-params">(assigns)</span> -&gt;</span>
    result = <span class="hljs-keyword">for</span> assign <span class="hljs-keyword">in</span> assigns
      variable = assign.variable
      base     = variable?.base
      value    = assign.value
      <span class="hljs-keyword">delete</span> assign.context

      <span class="hljs-keyword">if</span> base.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;constructor&#x27;</span>
        <span class="hljs-keyword">if</span> value <span class="hljs-keyword">instanceof</span> Code
          base.error <span class="hljs-string">&#x27;constructors must be defined at the top level of a class body&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-206">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-206">&#x00a7;</a>
              </div>
              <p>The class scope is not available yet, so return the assignment to update later</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        assign = @externalCtor = <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value, value
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> assign.variable.this
        name =
          <span class="hljs-keyword">if</span> base <span class="hljs-keyword">instanceof</span> ComputedPropertyName
            <span class="hljs-keyword">new</span> Index base.value
          <span class="hljs-keyword">else</span>
            <span class="hljs-keyword">new</span> (<span class="hljs-keyword">if</span> base.shouldCache() <span class="hljs-keyword">then</span> Index <span class="hljs-keyword">else</span> Access) base
        prototype = <span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> PropertyName <span class="hljs-string">&#x27;prototype&#x27;</span>
        variable  = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> ThisLiteral(), [ prototype, name ]

        assign.variable = variable
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> assign.value <span class="hljs-keyword">instanceof</span> Code
        assign.value.isStatic = <span class="hljs-literal">true</span>

      assign
    compact result

<span class="hljs-built_in">exports</span>.ClassProperty = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClassProperty</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">({@name, @isStatic, @staticClassName, @value, @operatorToken})</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;name&#x27;</span>, <span class="hljs-string">&#x27;value&#x27;</span>, <span class="hljs-string">&#x27;staticClassName&#x27;</span>]

  isStatement: YES

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      key: @name.ast o, LEVEL_LIST
      value: @value.ast o, LEVEL_LIST
      static: !!@isStatic
      computed: @name <span class="hljs-keyword">instanceof</span> Index <span class="hljs-keyword">or</span> @name <span class="hljs-keyword">instanceof</span> ComputedPropertyName
      operator: @operatorToken?.value ? <span class="hljs-string">&#x27;=&#x27;</span>
      staticClassName: @staticClassName?.ast(o) ? <span class="hljs-literal">null</span>

<span class="hljs-built_in">exports</span>.ClassPrototypeProperty = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClassPrototypeProperty</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">({@name, @value})</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;name&#x27;</span>, <span class="hljs-string">&#x27;value&#x27;</span>]

  isStatement: YES

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      key: @name.ast o, LEVEL_LIST
      value: @value.ast o, LEVEL_LIST
      computed: @name <span class="hljs-keyword">instanceof</span> ComputedPropertyName <span class="hljs-keyword">or</span> @name <span class="hljs-keyword">instanceof</span> StringWithInterpolations</pre></div></div>
            
        </li>
        
        
        <li id="section-207">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-207">&#x00a7;</a>
              </div>
              <h3 id="import-and-export">Import and Export</h3>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-built_in">exports</span>.ModuleDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ModuleDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@clause, @source, @assertions)</span> -&gt;</span>
    super()
    @checkSource()

  children: [<span class="hljs-string">&#x27;clause&#x27;</span>, <span class="hljs-string">&#x27;source&#x27;</span>, <span class="hljs-string">&#x27;assertions&#x27;</span>]

  isStatement: YES
  jumps:       THIS
  makeReturn:  THIS

  checkSource: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @source? <span class="hljs-keyword">and</span> @source <span class="hljs-keyword">instanceof</span> StringWithInterpolations
      @source.error <span class="hljs-string">&#x27;the name of the module to be imported from must be an uninterpolated string&#x27;</span>

  checkScope: <span class="hljs-function"><span class="hljs-params">(o, moduleDeclarationType)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-208">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-208">&#x00a7;</a>
              </div>
              <p>TODO: would be appropriate to flag this error during AST generation (as
well as when compiling to JS). But <code>o.indent</code> isn’t tracked during AST
generation, and there doesn’t seem to be a current alternative way to track
whether we’re at the “program top-level”.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> o.indent.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
      @error <span class="hljs-string">&quot;<span class="hljs-subst">#{moduleDeclarationType}</span> statements must be at top-level scope&quot;</span>

  astAssertions: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @assertions?.properties?
      @assertions.properties.map (assertion) =&gt;
        { start, end, loc, left, right } = assertion.ast(o)
        { type: <span class="hljs-string">&#x27;ImportAttribute&#x27;</span>, start, end, loc, key: left, value: right }
    <span class="hljs-keyword">else</span>
      []

<span class="hljs-built_in">exports</span>.ImportDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImportDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ModuleDeclaration</span></span>
  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkScope o, <span class="hljs-string">&#x27;import&#x27;</span>
    o.importedSymbols = []

    code = []
    code.push @makeCode <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span>import &quot;</span>
    code.push @clause.compileNode(o)... <span class="hljs-keyword">if</span> @clause?

    <span class="hljs-keyword">if</span> @source?.value?
      code.push @makeCode <span class="hljs-string">&#x27; from &#x27;</span> <span class="hljs-keyword">unless</span> @clause <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>
      code.push @makeCode @source.value
      <span class="hljs-keyword">if</span> @assertions?
        code.push @makeCode <span class="hljs-string">&#x27; assert &#x27;</span>
        code.push @assertions.compileToFragments(o)...

    code.push @makeCode <span class="hljs-string">&#x27;;&#x27;</span>
    code

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.importedSymbols = []
    super o

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    ret =
      specifiers: @clause?.ast(o) ? []
      source: @source.ast o
      assertions: @astAssertions(o)
    ret.importKind = <span class="hljs-string">&#x27;value&#x27;</span> <span class="hljs-keyword">if</span> @clause
    ret

<span class="hljs-built_in">exports</span>.ImportClause = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImportClause</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@defaultBinding, @namedImports)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;defaultBinding&#x27;</span>, <span class="hljs-string">&#x27;namedImports&#x27;</span>]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    code = []

    <span class="hljs-keyword">if</span> @defaultBinding?
      code.push @defaultBinding.compileNode(o)...
      code.push @makeCode <span class="hljs-string">&#x27;, &#x27;</span> <span class="hljs-keyword">if</span> @namedImports?

    <span class="hljs-keyword">if</span> @namedImports?
      code.push @namedImports.compileNode(o)...

    code

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-209">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-209">&#x00a7;</a>
              </div>
              <p>The AST for <code>ImportClause</code> is the non-nested list of import specifiers
that will be the <code>specifiers</code> property of an <code>ImportDeclaration</code> AST</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    compact flatten [
      @defaultBinding?.ast o
      @namedImports?.ast o
    ]

<span class="hljs-built_in">exports</span>.ExportDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExportDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ModuleDeclaration</span></span>
  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkScope o, <span class="hljs-string">&#x27;export&#x27;</span>
    @checkForAnonymousClassExport()

    code = []
    code.push @makeCode <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span>export &quot;</span>
    code.push @makeCode <span class="hljs-string">&#x27;default &#x27;</span> <span class="hljs-keyword">if</span> @ <span class="hljs-keyword">instanceof</span> ExportDefaultDeclaration

    <span class="hljs-keyword">if</span> @ <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> ExportDefaultDeclaration <span class="hljs-keyword">and</span>
       (@clause <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">or</span> @clause <span class="hljs-keyword">instanceof</span> Class)
      code.push @makeCode <span class="hljs-string">&#x27;var &#x27;</span>
      @clause.moduleDeclaration = <span class="hljs-string">&#x27;export&#x27;</span>

    <span class="hljs-keyword">if</span> @clause.body? <span class="hljs-keyword">and</span> @clause.body <span class="hljs-keyword">instanceof</span> Block
      code = code.concat @clause.compileToFragments o, LEVEL_TOP
    <span class="hljs-keyword">else</span>
      code = code.concat @clause.compileNode o

    <span class="hljs-keyword">if</span> @source?.value?
      code.push @makeCode <span class="hljs-string">&quot; from <span class="hljs-subst">#{@source.value}</span>&quot;</span>
      <span class="hljs-keyword">if</span> @assertions?
        code.push @makeCode <span class="hljs-string">&#x27; assert &#x27;</span>
        code.push @assertions.compileToFragments(o)...

    code.push @makeCode <span class="hljs-string">&#x27;;&#x27;</span>
    code</pre></div></div>
            
        </li>
        
        
        <li id="section-210">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-210">&#x00a7;</a>
              </div>
              <p>Prevent exporting an anonymous class; all exported members must be named</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  checkForAnonymousClassExport: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @ <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> ExportDefaultDeclaration <span class="hljs-keyword">and</span> @clause <span class="hljs-keyword">instanceof</span> Class <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @clause.variable
      @clause.error <span class="hljs-string">&#x27;anonymous classes cannot be exported&#x27;</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkForAnonymousClassExport()
    super o

<span class="hljs-built_in">exports</span>.ExportNamedDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExportNamedDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ExportDeclaration</span></span>
  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    ret =
      source: @source?.ast(o) ? <span class="hljs-literal">null</span>
      assertions: @astAssertions(o)
      exportKind: <span class="hljs-string">&#x27;value&#x27;</span>
    clauseAst = @clause.ast o
    <span class="hljs-keyword">if</span> @clause <span class="hljs-keyword">instanceof</span> ExportSpecifierList
      ret.specifiers = clauseAst
      ret.declaration = <span class="hljs-literal">null</span>
    <span class="hljs-keyword">else</span>
      ret.specifiers = []
      ret.declaration = clauseAst
    ret

<span class="hljs-built_in">exports</span>.ExportDefaultDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExportDefaultDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ExportDeclaration</span></span>
  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      declaration: @clause.ast o
      assertions: @astAssertions(o)

<span class="hljs-built_in">exports</span>.ExportAllDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExportAllDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ExportDeclaration</span></span>
  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      source: @source.ast o
      assertions: @astAssertions(o)
      exportKind: <span class="hljs-string">&#x27;value&#x27;</span>

<span class="hljs-built_in">exports</span>.ModuleSpecifierList = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ModuleSpecifierList</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@specifiers)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;specifiers&#x27;</span>]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    code = []
    o.indent += TAB
    compiledList = (specifier.compileToFragments o, LEVEL_LIST <span class="hljs-keyword">for</span> specifier <span class="hljs-keyword">in</span> @specifiers)

    <span class="hljs-keyword">if</span> @specifiers.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
      code.push @makeCode <span class="hljs-string">&quot;{\n<span class="hljs-subst">#{o.indent}</span>&quot;</span>
      <span class="hljs-keyword">for</span> fragments, index <span class="hljs-keyword">in</span> compiledList
        code.push @makeCode(<span class="hljs-string">&quot;,\n<span class="hljs-subst">#{o.indent}</span>&quot;</span>) <span class="hljs-keyword">if</span> index
        code.push fragments...
      code.push @makeCode <span class="hljs-string">&quot;\n}&quot;</span>
    <span class="hljs-keyword">else</span>
      code.push @makeCode <span class="hljs-string">&#x27;{}&#x27;</span>
    code

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    specifier.ast(o) <span class="hljs-keyword">for</span> specifier <span class="hljs-keyword">in</span> @specifiers

<span class="hljs-built_in">exports</span>.ImportSpecifierList = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImportSpecifierList</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ModuleSpecifierList</span></span>

<span class="hljs-built_in">exports</span>.ExportSpecifierList = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExportSpecifierList</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ModuleSpecifierList</span></span>

<span class="hljs-built_in">exports</span>.ModuleSpecifier = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ModuleSpecifier</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@original, @alias, @moduleDeclarationType)</span> -&gt;</span>
    super()

    <span class="hljs-keyword">if</span> @original.comments <span class="hljs-keyword">or</span> @alias?.comments
      @comments = []
      @comments.push @original.comments... <span class="hljs-keyword">if</span> @original.comments
      @comments.push @alias.comments...    <span class="hljs-keyword">if</span> @alias?.comments</pre></div></div>
            
        </li>
        
        
        <li id="section-211">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-211">&#x00a7;</a>
              </div>
              <p>The name of the variable entering the local scope</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @identifier = <span class="hljs-keyword">if</span> @alias? <span class="hljs-keyword">then</span> @alias.value <span class="hljs-keyword">else</span> @original.value

  children: [<span class="hljs-string">&#x27;original&#x27;</span>, <span class="hljs-string">&#x27;alias&#x27;</span>]

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @addIdentifierToScope o
    code = []
    code.push @makeCode @original.value
    code.push @makeCode <span class="hljs-string">&quot; as <span class="hljs-subst">#{@alias.value}</span>&quot;</span> <span class="hljs-keyword">if</span> @alias?
    code

  addIdentifierToScope: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.scope.find @identifier, @moduleDeclarationType

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @addIdentifierToScope o
    super o

<span class="hljs-built_in">exports</span>.ImportSpecifier = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImportSpecifier</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ModuleSpecifier</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(imported, local)</span> -&gt;</span>
    super imported, local, <span class="hljs-string">&#x27;import&#x27;</span>

  addIdentifierToScope: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-212">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-212">&#x00a7;</a>
              </div>
              <p>Per the spec, symbols can’t be imported multiple times
(e.g. <code>import { foo, foo } from &#39;lib&#39;</code> is invalid)</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @identifier <span class="hljs-keyword">in</span> o.importedSymbols <span class="hljs-keyword">or</span> o.scope.check(@identifier)
      @error <span class="hljs-string">&quot;&#x27;<span class="hljs-subst">#{@identifier}</span>&#x27; has already been declared&quot;</span>
    <span class="hljs-keyword">else</span>
      o.importedSymbols.push @identifier
    super o

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    originalAst = @original.ast o
    <span class="hljs-keyword">return</span>
      imported: originalAst
      local: @alias?.ast(o) ? originalAst
      importKind: <span class="hljs-literal">null</span>

<span class="hljs-built_in">exports</span>.ImportDefaultSpecifier = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImportDefaultSpecifier</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ImportSpecifier</span></span>
  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      local: @original.ast o

<span class="hljs-built_in">exports</span>.ImportNamespaceSpecifier = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImportNamespaceSpecifier</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ImportSpecifier</span></span>
  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      local: @alias.ast o

<span class="hljs-built_in">exports</span>.ExportSpecifier = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExportSpecifier</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ModuleSpecifier</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(local, exported)</span> -&gt;</span>
    super local, exported, <span class="hljs-string">&#x27;export&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    originalAst = @original.ast o
    <span class="hljs-keyword">return</span>
      local: originalAst
      exported: @alias?.ast(o) ? originalAst

<span class="hljs-built_in">exports</span>.DynamicImport = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DynamicImport</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  compileNode: <span class="hljs-function">-&gt;</span>
    [@makeCode <span class="hljs-string">&#x27;import&#x27;</span>]

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;Import&#x27;</span>

<span class="hljs-built_in">exports</span>.DynamicImportCall = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DynamicImportCall</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Call</span></span>
  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkArguments()
    super o

  checkArguments: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">unless</span> <span class="hljs-number">1</span> &lt;= @args.length &lt;= <span class="hljs-number">2</span>
      @error <span class="hljs-string">&#x27;import() accepts either one or two arguments&#x27;</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkArguments()
    super o</pre></div></div>
            
        </li>
        
        
        <li id="section-213">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-213">&#x00a7;</a>
              </div>
              <h3 id="assign">Assign</h3>

            </div>
            
        </li>
        
        
        <li id="section-214">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-214">&#x00a7;</a>
              </div>
              <p>The <strong>Assign</strong> is used to assign a local variable to value, or to set the
property of an object – including within object literals.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Assign = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Assign</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@variable, @value, @context, options = {})</span> -&gt;</span>
    super()
    {@param, @subpattern, @operatorToken, @moduleDeclaration, @originalContext = @context} = options
    @propagateLhs()

  children: [<span class="hljs-string">&#x27;variable&#x27;</span>, <span class="hljs-string">&#x27;value&#x27;</span>]

  isAssignable: YES

  isStatement: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o?.level <span class="hljs-keyword">is</span> LEVEL_TOP <span class="hljs-keyword">and</span> @context? <span class="hljs-keyword">and</span> (@moduleDeclaration <span class="hljs-keyword">or</span> <span class="hljs-string">&quot;?&quot;</span> <span class="hljs-keyword">in</span> @context)

  checkNameAssignability: <span class="hljs-function"><span class="hljs-params">(o, varBase)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> o.scope.type(varBase.value) <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;import&#x27;</span>
      varBase.error <span class="hljs-string">&quot;&#x27;<span class="hljs-subst">#{varBase.value}</span>&#x27; is read-only&quot;</span>

  assigns: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    @[<span class="hljs-keyword">if</span> @context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span> <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;value&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;variable&#x27;</span>].assigns name

  unfoldSoak: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    unfoldSoak o, this, <span class="hljs-string">&#x27;variable&#x27;</span>

  addScopeVariables: (o, {</pre></div></div>
            
        </li>
        
        
        <li id="section-215">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-215">&#x00a7;</a>
              </div>
              <p>During AST generation, we need to allow assignment to these constructs
that are considered “unassignable” during compile-to-JS, while still
flagging things like <code>[null] = b</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    allowAssignmentToExpansion = <span class="hljs-literal">no</span>,
    allowAssignmentToNontrailingSplat = <span class="hljs-literal">no</span>,
    allowAssignmentToEmptyArray = <span class="hljs-literal">no</span>,
    allowAssignmentToComplexSplat = <span class="hljs-literal">no</span>
  } = {}) -&gt;
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> <span class="hljs-keyword">not</span> @context <span class="hljs-keyword">or</span> @context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;**=&#x27;</span>

    varBase = @variable.unwrapAll()
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> varBase.isAssignable {
      allowExpansion: allowAssignmentToExpansion
      allowNontrailingSplat: allowAssignmentToNontrailingSplat
      allowEmptyArray: allowAssignmentToEmptyArray
      allowComplexSplat: allowAssignmentToComplexSplat
    }
      @variable.error <span class="hljs-string">&quot;&#x27;<span class="hljs-subst">#{@variable.compile o}</span>&#x27; can&#x27;t be assigned&quot;</span>

    varBase.eachName (name) =&gt;
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> name.hasProperties?()

      message = isUnassignable name.value
      name.error message <span class="hljs-keyword">if</span> message</pre></div></div>
            
        </li>
        
        
        <li id="section-216">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-216">&#x00a7;</a>
              </div>
              <p><code>moduleDeclaration</code> can be <code>&#39;import&#39;</code> or <code>&#39;export&#39;</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      @checkNameAssignability o, name
      <span class="hljs-keyword">if</span> @moduleDeclaration
        o.scope.add name.value, @moduleDeclaration
        name.isDeclaration = <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @param
        o.scope.add name.value,
          <span class="hljs-keyword">if</span> @param <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;alwaysDeclare&#x27;</span>
            <span class="hljs-string">&#x27;var&#x27;</span>
          <span class="hljs-keyword">else</span>
            <span class="hljs-string">&#x27;param&#x27;</span>
      <span class="hljs-keyword">else</span>
        alreadyDeclared = o.scope.find name.value
        name.isDeclaration ?= <span class="hljs-keyword">not</span> alreadyDeclared</pre></div></div>
            
        </li>
        
        
        <li id="section-217">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-217">&#x00a7;</a>
              </div>
              <p>If this assignment identifier has one or more herecomments
attached, output them as part of the declarations line (unless
other herecomments are already staged there) for compatibility
with Flow typing. Don’t do this if this assignment is for a
class, e.g. <code>ClassName = class ClassName {</code>, as Flow requires
the comment to be between the class name and the <code>{</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">if</span> name.comments <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> o.scope.comments[name.value] <span class="hljs-keyword">and</span>
           @value <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Class <span class="hljs-keyword">and</span>
           name.comments.every(<span class="hljs-function"><span class="hljs-params">(comment)</span> -&gt;</span> comment.here <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> comment.multiline)
          commentsNode = <span class="hljs-keyword">new</span> IdentifierLiteral name.value
          commentsNode.comments = name.comments
          commentFragments = []
          @compileCommentFragments o, commentsNode, commentFragments
          o.scope.comments[name.value] = commentFragments</pre></div></div>
            
        </li>
        
        
        <li id="section-218">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-218">&#x00a7;</a>
              </div>
              <p>Compile an assignment, delegating to <code>compileDestructuring</code> or
<code>compileSplice</code> if appropriate. Keep track of the name of the base object
we’ve been assigned to, for correct internal references. If the variable
has not been seen yet within the current scope, declare it.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    isValue = @variable <span class="hljs-keyword">instanceof</span> Value
    <span class="hljs-keyword">if</span> isValue</pre></div></div>
            
        </li>
        
        
        <li id="section-219">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-219">&#x00a7;</a>
              </div>
              <p>If <code>@variable</code> is an array or an object, we’re destructuring;
if it’s also <code>isAssignable()</code>, the destructuring syntax is supported
in ES and we can output it as is; otherwise we <code>@compileDestructuring</code>
and convert this ES-unsupported destructuring into acceptable output.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> @variable.isArray() <span class="hljs-keyword">or</span> @variable.isObject()
        <span class="hljs-keyword">unless</span> @variable.isAssignable()
          <span class="hljs-keyword">if</span> @variable.isObject() <span class="hljs-keyword">and</span> @variable.base.hasSplat()
            <span class="hljs-keyword">return</span> @compileObjectDestruct o
          <span class="hljs-keyword">else</span>
            <span class="hljs-keyword">return</span> @compileDestructuring o

      <span class="hljs-keyword">return</span> @compileSplice       o <span class="hljs-keyword">if</span> @variable.isSplice()
      <span class="hljs-keyword">return</span> @compileConditional  o <span class="hljs-keyword">if</span> @isConditional()
      <span class="hljs-keyword">return</span> @compileSpecialMath  o <span class="hljs-keyword">if</span> @context <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;//=&#x27;</span>, <span class="hljs-string">&#x27;%%=&#x27;</span>]

    @addScopeVariables o
    <span class="hljs-keyword">if</span> @value <span class="hljs-keyword">instanceof</span> Code
      <span class="hljs-keyword">if</span> @value.isStatic
        @value.name = @variable.properties[<span class="hljs-number">0</span>]
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @variable.properties?.length &gt;= <span class="hljs-number">2</span>
        [properties..., prototype, name] = @variable.properties
        @value.name = name <span class="hljs-keyword">if</span> prototype.name?.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;prototype&#x27;</span>

    val = @value.compileToFragments o, LEVEL_LIST
    compiledName = @variable.compileToFragments o, LEVEL_LIST

    <span class="hljs-keyword">if</span> @context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span>
      <span class="hljs-keyword">if</span> @variable.shouldCache()
        compiledName.unshift @makeCode <span class="hljs-string">&#x27;[&#x27;</span>
        compiledName.push @makeCode <span class="hljs-string">&#x27;]&#x27;</span>
      <span class="hljs-keyword">return</span> compiledName.concat @makeCode(<span class="hljs-string">&#x27;: &#x27;</span>), val

    answer = compiledName.concat @makeCode(<span class="hljs-string">&quot; <span class="hljs-subst">#{ @context <span class="hljs-keyword">or</span> <span class="hljs-string">&#x27;=&#x27;</span> }</span> &quot;</span>), val</pre></div></div>
            
        </li>
        
        
        <li id="section-220">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-220">&#x00a7;</a>
              </div>
              <p>Per <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration</a>,
if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
The assignment is wrapped in parentheses if ‘o.level’ has lower precedence than LEVEL_LIST (3)
(i.e. LEVEL_COND (4), LEVEL_OP (5) or LEVEL_ACCESS (6)), or if we’re destructuring object, e.g. {a,b} = obj.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> o.level &gt; LEVEL_LIST <span class="hljs-keyword">or</span> isValue <span class="hljs-keyword">and</span> @variable.base <span class="hljs-keyword">instanceof</span> Obj <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @nestedLhs <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> (@param <span class="hljs-keyword">is</span> <span class="hljs-literal">yes</span>)
      @wrapInParentheses answer
    <span class="hljs-keyword">else</span>
      answer</pre></div></div>
            
        </li>
        
        
        <li id="section-221">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-221">&#x00a7;</a>
              </div>
              <p>Object rest property is not assignable: <code>{{a}...}</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileObjectDestruct: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @variable.base.reorderProperties()
    {properties: props} = @variable.base
    [..., splat] = props
    splatProp = splat.name
    assigns = []
    refVal = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;ref&#x27;</span>
    props.splice <span class="hljs-number">-1</span>, <span class="hljs-number">1</span>, <span class="hljs-keyword">new</span> Splat refVal
    assigns.push <span class="hljs-keyword">new</span> Assign(<span class="hljs-keyword">new</span> Value(<span class="hljs-keyword">new</span> Obj props), @value).compileToFragments o, LEVEL_LIST
    assigns.push <span class="hljs-keyword">new</span> Assign(<span class="hljs-keyword">new</span> Value(splatProp), refVal).compileToFragments o, LEVEL_LIST
    @joinFragmentArrays assigns, <span class="hljs-string">&#x27;, &#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-222">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-222">&#x00a7;</a>
              </div>
              <p>Brief implementation of recursive pattern matching, when assigning array or
object literals to a value. Peeks at their properties to assign inner names.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileDestructuring: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    top       = o.level <span class="hljs-keyword">is</span> LEVEL_TOP
    {value}   = this
    {objects} = @variable.base
    olen      = objects.length</pre></div></div>
            
        </li>
        
        
        <li id="section-223">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-223">&#x00a7;</a>
              </div>
              <p>Special-case for <code>{} = a</code> and <code>[] = a</code> (empty patterns).
Compile to simply <code>a</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> olen <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
      code = value.compileToFragments o
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_OP <span class="hljs-keyword">then</span> @wrapInParentheses code <span class="hljs-keyword">else</span> code
    [obj] = objects

    @disallowLoneExpansion()
    {splats, expans, splatsAndExpans} = @getAndCheckSplatsAndExpansions()

    isSplat = splats?.length &gt; <span class="hljs-number">0</span>
    isExpans = expans?.length &gt; <span class="hljs-number">0</span>

    vvar     = value.compileToFragments o, LEVEL_LIST
    vvarText = fragmentsToText vvar
    assigns  = []
<span class="hljs-function">    <span class="hljs-title">pushAssign</span> = <span class="hljs-params">(variable, val)</span> =&gt;</span>
      assigns.push <span class="hljs-keyword">new</span> Assign(variable, val, <span class="hljs-literal">null</span>, param: @param, subpattern: <span class="hljs-literal">yes</span>).compileToFragments o, LEVEL_LIST

    <span class="hljs-keyword">if</span> isSplat
      splatVar = objects[splats[<span class="hljs-number">0</span>]].name.unwrap()
      <span class="hljs-keyword">if</span> splatVar <span class="hljs-keyword">instanceof</span> Arr <span class="hljs-keyword">or</span> splatVar <span class="hljs-keyword">instanceof</span> Obj
        splatVarRef = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;ref&#x27;</span>
        objects[splats[<span class="hljs-number">0</span>]].name = splatVarRef
<span class="hljs-function">        <span class="hljs-title">splatVarAssign</span> = -&gt;</span> pushAssign <span class="hljs-keyword">new</span> Value(splatVar), splatVarRef</pre></div></div>
            
        </li>
        
        
        <li id="section-224">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-224">&#x00a7;</a>
              </div>
              <p>At this point, there are several things to destructure. So the <code>fn()</code> in
<code>{a, b} = fn()</code> must be cached, for example. Make vvar into a simple
variable if it isn’t already.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> value.unwrap() <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> IdentifierLiteral <span class="hljs-keyword">or</span> @variable.assigns(vvarText)
      ref = o.scope.freeVariable <span class="hljs-string">&#x27;ref&#x27;</span>
      assigns.push [@makeCode(ref + <span class="hljs-string">&#x27; = &#x27;</span>), vvar...]
      vvar = [@makeCode ref]
      vvarText = ref
<span class="hljs-function">
    <span class="hljs-title">slicer</span> = <span class="hljs-params">(type)</span> -&gt;</span> (vvar, start, end = <span class="hljs-literal">no</span>) -&gt;
      vvar = <span class="hljs-keyword">new</span> IdentifierLiteral vvar <span class="hljs-keyword">unless</span> vvar <span class="hljs-keyword">instanceof</span> Value
      args = [vvar, <span class="hljs-keyword">new</span> NumberLiteral(start)]
      args.push <span class="hljs-keyword">new</span> NumberLiteral end <span class="hljs-keyword">if</span> end
      slice = <span class="hljs-keyword">new</span> Value (<span class="hljs-keyword">new</span> IdentifierLiteral utility type, o), [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> PropertyName <span class="hljs-string">&#x27;call&#x27;</span>]
      <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Call slice, args</pre></div></div>
            
        </li>
        
        
        <li id="section-225">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-225">&#x00a7;</a>
              </div>
              <p>Helper which outputs <code>[].slice</code> code.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    compSlice = slicer <span class="hljs-string">&quot;slice&quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-226">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-226">&#x00a7;</a>
              </div>
              <p>Helper which outputs <code>[].splice</code> code.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    compSplice = slicer <span class="hljs-string">&quot;splice&quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-227">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-227">&#x00a7;</a>
              </div>
              <p>Check if <code>objects</code> array contains any instance of <code>Assign</code>, e.g. {a:1}.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function">    <span class="hljs-title">hasObjAssigns</span> = <span class="hljs-params">(objs)</span> -&gt;</span>
      (i <span class="hljs-keyword">for</span> obj, i <span class="hljs-keyword">in</span> objs <span class="hljs-keyword">when</span> obj <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> obj.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span>)</pre></div></div>
            
        </li>
        
        
        <li id="section-228">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-228">&#x00a7;</a>
              </div>
              <p>Check if <code>objects</code> array contains any unassignable object.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function">    <span class="hljs-title">objIsUnassignable</span> = <span class="hljs-params">(objs)</span> -&gt;</span>
      <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> objs <span class="hljs-keyword">when</span> <span class="hljs-keyword">not</span> obj.isAssignable()
      <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-229">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-229">&#x00a7;</a>
              </div>
              <p><code>objects</code> are complex when there is object assign ({a:1}),
unassignable object, or just a single node.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function">    <span class="hljs-title">complexObjects</span> = <span class="hljs-params">(objs)</span> -&gt;</span>
      hasObjAssigns(objs).length <span class="hljs-keyword">or</span> objIsUnassignable(objs) <span class="hljs-keyword">or</span> olen <span class="hljs-keyword">is</span> <span class="hljs-number">1</span></pre></div></div>
            
        </li>
        
        
        <li id="section-230">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-230">&#x00a7;</a>
              </div>
              <p>“Complex” <code>objects</code> are processed in a loop.
Examples: [a, b, {c, r…}, d], [a, …, {b, r…}, c, d]</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function">    <span class="hljs-title">loopObjects</span> = <span class="hljs-params">(objs, vvar, vvarTxt)</span> =&gt;</span>
      <span class="hljs-keyword">for</span> obj, i <span class="hljs-keyword">in</span> objs</pre></div></div>
            
        </li>
        
        
        <li id="section-231">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-231">&#x00a7;</a>
              </div>
              <p><code>Elision</code> can be skipped.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">continue</span> <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Elision</pre></div></div>
            
        </li>
        
        
        <li id="section-232">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-232">&#x00a7;</a>
              </div>
              <p>If <code>obj</code> is {a: 1}</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> obj.context <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;object&#x27;</span>
          {variable: {base: idx}, value: vvar} = obj
          {variable: vvar} = vvar <span class="hljs-keyword">if</span> vvar <span class="hljs-keyword">instanceof</span> Assign
          idx =
            <span class="hljs-keyword">if</span> vvar.this
              vvar.properties[<span class="hljs-number">0</span>].name
            <span class="hljs-keyword">else</span>
              <span class="hljs-keyword">new</span> PropertyName vvar.unwrap().value
          acc = idx.unwrap() <span class="hljs-keyword">instanceof</span> PropertyName
          vval = <span class="hljs-keyword">new</span> Value value, [<span class="hljs-keyword">new</span> (<span class="hljs-keyword">if</span> acc <span class="hljs-keyword">then</span> Access <span class="hljs-keyword">else</span> Index) idx]
        <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-233">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-233">&#x00a7;</a>
              </div>
              <p><code>obj</code> is [a…], {a…} or a</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          vvar = <span class="hljs-keyword">switch</span>
            <span class="hljs-keyword">when</span> obj <span class="hljs-keyword">instanceof</span> Splat <span class="hljs-keyword">then</span> <span class="hljs-keyword">new</span> Value obj.name
            <span class="hljs-keyword">else</span> obj
          vval = <span class="hljs-keyword">switch</span>
            <span class="hljs-keyword">when</span> obj <span class="hljs-keyword">instanceof</span> Splat <span class="hljs-keyword">then</span> compSlice(vvarTxt, i)
            <span class="hljs-keyword">else</span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal(vvarTxt), [<span class="hljs-keyword">new</span> Index <span class="hljs-keyword">new</span> NumberLiteral i]
        message = isUnassignable vvar.unwrap().value
        vvar.error message <span class="hljs-keyword">if</span> message
        pushAssign vvar, vval</pre></div></div>
            
        </li>
        
        
        <li id="section-234">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-234">&#x00a7;</a>
              </div>
              <p>“Simple” <code>objects</code> can be split and compiled to arrays, [a, b, c] = arr, [a, b, c…] = arr</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function">    <span class="hljs-title">assignObjects</span> = <span class="hljs-params">(objs, vvar, vvarTxt)</span> =&gt;</span>
      vvar = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Arr(objs, <span class="hljs-literal">yes</span>)
      vval = <span class="hljs-keyword">if</span> vvarTxt <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">then</span> vvarTxt <span class="hljs-keyword">else</span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal(vvarTxt)
      pushAssign vvar, vval
<span class="hljs-function">
    <span class="hljs-title">processObjects</span> = <span class="hljs-params">(objs, vvar, vvarTxt)</span> -&gt;</span>
      <span class="hljs-keyword">if</span> complexObjects objs
        loopObjects objs, vvar, vvarTxt
      <span class="hljs-keyword">else</span>
        assignObjects objs, vvar, vvarTxt</pre></div></div>
            
        </li>
        
        
        <li id="section-235">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-235">&#x00a7;</a>
              </div>
              <p>In case there is <code>Splat</code> or <code>Expansion</code> in <code>objects</code>,
we can split array in two simple subarrays.
<code>Splat</code> [a, b, c…, d, e] can be split into  [a, b, c…] and [d, e].
<code>Expansion</code> [a, b, …, c, d] can be split into [a, b] and [c, d].
Examples:
a) <code>Splat</code>
  CS: [a, b, c…, d, e] = arr
  JS: [a, b, …c] = arr, [d, e] = splice.call(c, -2)
b) <code>Expansion</code>
  CS: [a, b, …, d, e] = arr
  JS: [a, b] = arr, [d, e] = slice.call(arr, -2)</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> splatsAndExpans.length
      expIdx = splatsAndExpans[<span class="hljs-number">0</span>]
      leftObjs = objects.slice <span class="hljs-number">0</span>, expIdx + (<span class="hljs-keyword">if</span> isSplat <span class="hljs-keyword">then</span> <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> <span class="hljs-number">0</span>)
      rightObjs = objects.slice expIdx + <span class="hljs-number">1</span>
      processObjects leftObjs, vvar, vvarText <span class="hljs-keyword">if</span> leftObjs.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
      <span class="hljs-keyword">if</span> rightObjs.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span></pre></div></div>
            
        </li>
        
        
        <li id="section-236">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-236">&#x00a7;</a>
              </div>
              <p>Slice or splice <code>objects</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        refExp = <span class="hljs-keyword">switch</span>
          <span class="hljs-keyword">when</span> isSplat <span class="hljs-keyword">then</span> compSplice <span class="hljs-keyword">new</span> Value(objects[expIdx].name), rightObjs.length * <span class="hljs-number">-1</span>
          <span class="hljs-keyword">when</span> isExpans <span class="hljs-keyword">then</span> compSlice vvarText, rightObjs.length * <span class="hljs-number">-1</span>
        <span class="hljs-keyword">if</span> complexObjects rightObjs
          restVar = refExp
          refExp = o.scope.freeVariable <span class="hljs-string">&#x27;ref&#x27;</span>
          assigns.push [@makeCode(refExp + <span class="hljs-string">&#x27; = &#x27;</span>), restVar.compileToFragments(o, LEVEL_LIST)...]
        processObjects rightObjs, vvar, refExp
    <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-237">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-237">&#x00a7;</a>
              </div>
              <p>There is no <code>Splat</code> or <code>Expansion</code> in <code>objects</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      processObjects objects, vvar, vvarText
    splatVarAssign?()
    assigns.push vvar <span class="hljs-keyword">unless</span> top <span class="hljs-keyword">or</span> @subpattern
    fragments = @joinFragmentArrays assigns, <span class="hljs-string">&#x27;, &#x27;</span>
    <span class="hljs-keyword">if</span> o.level &lt; LEVEL_LIST <span class="hljs-keyword">then</span> fragments <span class="hljs-keyword">else</span> @wrapInParentheses fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-238">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-238">&#x00a7;</a>
              </div>
              <p>Disallow <code>[...] = a</code> for some reason. (Could be equivalent to <code>[] = a</code>?)</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  disallowLoneExpansion: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> @variable.base <span class="hljs-keyword">instanceof</span> Arr
    {objects} = @variable.base
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> objects?.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
    [loneObject] = objects
    <span class="hljs-keyword">if</span> loneObject <span class="hljs-keyword">instanceof</span> Expansion
      loneObject.error <span class="hljs-string">&#x27;Destructuring assignment has no target&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-239">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-239">&#x00a7;</a>
              </div>
              <p>Show error if there is more than one <code>Splat</code>, or <code>Expansion</code>.
Examples: [a, b, c…, d, e, f…], [a, b, …, c, d, …], [a, b, …, c, d, e…]</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  getAndCheckSplatsAndExpansions: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> {splats: [], expans: [], splatsAndExpans: []} <span class="hljs-keyword">unless</span> @variable.base <span class="hljs-keyword">instanceof</span> Arr
    {objects} = @variable.base</pre></div></div>
            
        </li>
        
        
        <li id="section-240">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-240">&#x00a7;</a>
              </div>
              <p>Count all <code>Splats</code>: [a, b, c…, d, e]</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    splats = (i <span class="hljs-keyword">for</span> obj, i <span class="hljs-keyword">in</span> objects <span class="hljs-keyword">when</span> obj <span class="hljs-keyword">instanceof</span> Splat)</pre></div></div>
            
        </li>
        
        
        <li id="section-241">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-241">&#x00a7;</a>
              </div>
              <p>Count all <code>Expansions</code>: [a, b, …, c, d]</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    expans = (i <span class="hljs-keyword">for</span> obj, i <span class="hljs-keyword">in</span> objects <span class="hljs-keyword">when</span> obj <span class="hljs-keyword">instanceof</span> Expansion)</pre></div></div>
            
        </li>
        
        
        <li id="section-242">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-242">&#x00a7;</a>
              </div>
              <p>Combine splats and expansions.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    splatsAndExpans = [splats..., expans...]
    <span class="hljs-keyword">if</span> splatsAndExpans.length &gt; <span class="hljs-number">1</span></pre></div></div>
            
        </li>
        
        
        <li id="section-243">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-243">&#x00a7;</a>
              </div>
              <p>Sort ‘splatsAndExpans’ so we can show error at first disallowed token.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      objects[splatsAndExpans.sort()[<span class="hljs-number">1</span>]].error <span class="hljs-string">&quot;multiple splats/expansions are disallowed in an assignment&quot;</span>
    {splats, expans, splatsAndExpans}</pre></div></div>
            
        </li>
        
        
        <li id="section-244">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-244">&#x00a7;</a>
              </div>
              <p>When compiling a conditional assignment, take care to ensure that the
operands are only evaluated once, even though we have to reference them
more than once.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileConditional: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [left, right] = @variable.cacheReference o</pre></div></div>
            
        </li>
        
        
        <li id="section-245">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-245">&#x00a7;</a>
              </div>
              <p>Disallow conditional assignment of undefined variables.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> left.properties.length <span class="hljs-keyword">and</span> left.base <span class="hljs-keyword">instanceof</span> Literal <span class="hljs-keyword">and</span>
           left.base <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> ThisLiteral <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> o.scope.check left.base.value
      @throwUnassignableConditionalError left.base.value
    <span class="hljs-keyword">if</span> <span class="hljs-string">&quot;?&quot;</span> <span class="hljs-keyword">in</span> @context
      o.isExistentialEquals = <span class="hljs-literal">true</span>
      <span class="hljs-keyword">new</span> If(<span class="hljs-keyword">new</span> Existence(left), right, type: <span class="hljs-string">&#x27;if&#x27;</span>).addElse(<span class="hljs-keyword">new</span> Assign(right, @value, <span class="hljs-string">&#x27;=&#x27;</span>)).compileToFragments o
    <span class="hljs-keyword">else</span>
      fragments = <span class="hljs-keyword">new</span> Op(@context[...<span class="hljs-number">-1</span>], left, <span class="hljs-keyword">new</span> Assign(right, @value, <span class="hljs-string">&#x27;=&#x27;</span>)).compileToFragments o
      <span class="hljs-keyword">if</span> o.level &lt;= LEVEL_LIST <span class="hljs-keyword">then</span> fragments <span class="hljs-keyword">else</span> @wrapInParentheses fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-246">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-246">&#x00a7;</a>
              </div>
              <p>Convert special math assignment operators like <code>a //= b</code> to the equivalent
extended form <code>a = a ** b</code> and then compiles that.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileSpecialMath: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [left, right] = @variable.cacheReference o
    <span class="hljs-keyword">new</span> Assign(left, <span class="hljs-keyword">new</span> Op(@context[...<span class="hljs-number">-1</span>], right, @value)).compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-247">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-247">&#x00a7;</a>
              </div>
              <p>Compile the assignment from an array splice literal, using JavaScript’s
<code>Array#splice</code> method.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileSplice: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    {range: {<span class="hljs-keyword">from</span>, to, exclusive}} = @variable.properties.pop()
    unwrappedVar = @variable.unwrapAll()
    <span class="hljs-keyword">if</span> unwrappedVar.comments
      moveComments unwrappedVar, @
      <span class="hljs-keyword">delete</span> @variable.comments
    name = @variable.compile o
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">from</span>
      [fromDecl, fromRef] = @cacheToCodeFragments <span class="hljs-keyword">from</span>.cache o, LEVEL_OP
    <span class="hljs-keyword">else</span>
      fromDecl = fromRef = <span class="hljs-string">&#x27;0&#x27;</span>
    <span class="hljs-keyword">if</span> to
      <span class="hljs-keyword">if</span> <span class="hljs-keyword">from</span>?.isNumber() <span class="hljs-keyword">and</span> to.isNumber()
        to = to.compile(o) - fromRef
        to += <span class="hljs-number">1</span> <span class="hljs-keyword">unless</span> exclusive
      <span class="hljs-keyword">else</span>
        to = to.compile(o, LEVEL_ACCESS) + <span class="hljs-string">&#x27; - &#x27;</span> + fromRef
        to += <span class="hljs-string">&#x27; + 1&#x27;</span> <span class="hljs-keyword">unless</span> exclusive
    <span class="hljs-keyword">else</span>
      to = <span class="hljs-string">&quot;9e9&quot;</span>
    [valDef, valRef] = @value.cache o, LEVEL_LIST
    answer = [].concat @makeCode(<span class="hljs-string">&quot;<span class="hljs-subst">#{utility <span class="hljs-string">&#x27;splice&#x27;</span>, o}</span>.apply(<span class="hljs-subst">#{name}</span>, [<span class="hljs-subst">#{fromDecl}</span>, <span class="hljs-subst">#{to}</span>].concat(&quot;</span>), valDef, @makeCode(<span class="hljs-string">&quot;)), &quot;</span>), valRef
    <span class="hljs-keyword">if</span> o.level &gt; LEVEL_TOP <span class="hljs-keyword">then</span> @wrapInParentheses answer <span class="hljs-keyword">else</span> answer

  eachName: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span>
    @variable.unwrapAll().eachName iterator

  isDefaultAssignment: <span class="hljs-function">-&gt;</span> @param <span class="hljs-keyword">or</span> @nestedLhs

  propagateLhs: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> @variable?.isArray?() <span class="hljs-keyword">or</span> @variable?.isObject?()</pre></div></div>
            
        </li>
        
        
        <li id="section-248">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-248">&#x00a7;</a>
              </div>
              <p>This is the left-hand side of an assignment; let <code>Arr</code> and <code>Obj</code>
know that, so that those nodes know that they’re assignable as
destructured variables.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @variable.base.propagateLhs <span class="hljs-literal">yes</span>

  throwUnassignableConditionalError: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    @variable.error <span class="hljs-string">&quot;the variable \&quot;<span class="hljs-subst">#{name}</span>\&quot; can&#x27;t be assigned with <span class="hljs-subst">#{@context}</span> because it has not been declared before&quot;</span>

  isConditional: <span class="hljs-function">-&gt;</span>
    @context <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;||=&#x27;</span>, <span class="hljs-string">&#x27;&amp;&amp;=&#x27;</span>, <span class="hljs-string">&#x27;?=&#x27;</span>]

  isStatementAst: NO

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @disallowLoneExpansion()
    @getAndCheckSplatsAndExpansions()
    <span class="hljs-keyword">if</span> @isConditional()
      variable = @variable.unwrap()
      <span class="hljs-keyword">if</span> variable <span class="hljs-keyword">instanceof</span> IdentifierLiteral <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> o.scope.check variable.value
        @throwUnassignableConditionalError variable.value
    @addScopeVariables o, allowAssignmentToExpansion: <span class="hljs-literal">yes</span>, allowAssignmentToNontrailingSplat: <span class="hljs-literal">yes</span>, allowAssignmentToEmptyArray: <span class="hljs-literal">yes</span>, allowAssignmentToComplexSplat: <span class="hljs-literal">yes</span>
    super o

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isDefaultAssignment()
      <span class="hljs-string">&#x27;AssignmentPattern&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;AssignmentExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    ret =
      right: @value.ast o, LEVEL_LIST
      left: @variable.ast o, LEVEL_LIST

    <span class="hljs-keyword">unless</span> @isDefaultAssignment()
      ret.operator = @originalContext ? <span class="hljs-string">&#x27;=&#x27;</span>

    ret</pre></div></div>
            
        </li>
        
        
        <li id="section-249">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-249">&#x00a7;</a>
              </div>
              <h3 id="funcglyph">FuncGlyph</h3>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-built_in">exports</span>.FuncGlyph = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FuncGlyph</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@glyph)</span> -&gt;</span>
    super()</pre></div></div>
            
        </li>
        
        
        <li id="section-250">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-250">&#x00a7;</a>
              </div>
              <h3 id="code">Code</h3>

            </div>
            
        </li>
        
        
        <li id="section-251">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-251">&#x00a7;</a>
              </div>
              <p>A function definition. This is the only node that creates a new Scope.
When for the purposes of walking the contents of a function body, the Code
has no <em>children</em> – they’re within the inner scope.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Code = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Code</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(params, body, @funcGlyph, @paramStart)</span> -&gt;</span>
    super()

    @params      = params <span class="hljs-keyword">or</span> []
    @body        = body <span class="hljs-keyword">or</span> <span class="hljs-keyword">new</span> Block
    @bound       = @funcGlyph?.glyph <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;=&gt;&#x27;</span>
    @isGenerator = <span class="hljs-literal">no</span>
    @isAsync     = <span class="hljs-literal">no</span>
    @isMethod    = <span class="hljs-literal">no</span>

    @body.traverseChildren <span class="hljs-literal">no</span>, <span class="hljs-function"><span class="hljs-params">(node)</span> =&gt;</span>
      <span class="hljs-keyword">if</span> (node <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> node.isYield()) <span class="hljs-keyword">or</span> node <span class="hljs-keyword">instanceof</span> YieldReturn
        @isGenerator = <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">if</span> (node <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> node.isAwait()) <span class="hljs-keyword">or</span> node <span class="hljs-keyword">instanceof</span> AwaitReturn
        @isAsync = <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> For <span class="hljs-keyword">and</span> node.isAwait()
        @isAsync = <span class="hljs-literal">yes</span>

    @propagateLhs()

  children: [<span class="hljs-string">&#x27;params&#x27;</span>, <span class="hljs-string">&#x27;body&#x27;</span>]

  isStatement: <span class="hljs-function">-&gt;</span> @isMethod

  jumps: NO

  makeScope: <span class="hljs-function"><span class="hljs-params">(parentScope)</span> -&gt;</span> <span class="hljs-keyword">new</span> Scope parentScope, @body, this</pre></div></div>
            
        </li>
        
        
        <li id="section-252">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-252">&#x00a7;</a>
              </div>
              <p>Compilation creates a new scope unless explicitly asked to share with the
outer scope. Handles splat parameters in the parameter list by setting
such parameters to be the final parameter in the function definition, as
required per the ES2015 spec. If the CoffeeScript function definition had
parameters after the splat, they are declared via expressions in the
function body.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkForAsyncOrGeneratorConstructor()

    <span class="hljs-keyword">if</span> @bound
      @context = o.scope.method.context <span class="hljs-keyword">if</span> o.scope.method?.bound
      @context = <span class="hljs-string">&#x27;this&#x27;</span> <span class="hljs-keyword">unless</span> @context

    @updateOptions o
    params           = []
    exprs            = []
    thisAssignments  = @thisAssignments?.slice() ? []
    paramsAfterSplat = []
    haveSplatParam   = <span class="hljs-literal">no</span>
    haveBodyParam    = <span class="hljs-literal">no</span>

    @checkForDuplicateParams()
    @disallowLoneExpansionAndMultipleSplats()</pre></div></div>
            
        </li>
        
        
        <li id="section-253">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-253">&#x00a7;</a>
              </div>
              <p>Separate <code>this</code> assignments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @eachParamName (name, node, param, obj) -&gt;
      <span class="hljs-keyword">if</span> node.this
        name   = node.properties[<span class="hljs-number">0</span>].name.value
        name   = <span class="hljs-string">&quot;_<span class="hljs-subst">#{name}</span>&quot;</span> <span class="hljs-keyword">if</span> name <span class="hljs-keyword">in</span> JS_FORBIDDEN
        target = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable name, reserve: <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-254">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-254">&#x00a7;</a>
              </div>
              <p><code>Param</code> is object destructuring with a default value: ({@prop = 1}) -&gt;
In a case when the variable name is already reserved, we have to assign
a new variable name to the destructured variable: ({prop:prop1 = 1}) -&gt;</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        replacement =
            <span class="hljs-keyword">if</span> param.name <span class="hljs-keyword">instanceof</span> Obj <span class="hljs-keyword">and</span> obj <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span>
                obj.operatorToken.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;=&#x27;</span>
              <span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> IdentifierLiteral name), target, <span class="hljs-string">&#x27;object&#x27;</span> <span class="hljs-comment">#, operatorToken: new Literal &#x27;:&#x27;</span>
            <span class="hljs-keyword">else</span>
              target
        param.renameParam node, replacement
        thisAssignments.push <span class="hljs-keyword">new</span> Assign node, target</pre></div></div>
            
        </li>
        
        
        <li id="section-255">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-255">&#x00a7;</a>
              </div>
              <p>Parse the parameters, adding them to the list of parameters to put in the
function definition; and dealing with splats or expansions, including
adding expressions to the function body to declare all parameter
variables that would have been after the splat/expansion parameter.
If we encounter a parameter that needs to be declared in the function
body for any reason, for example it’s destructured with <code>this</code>, also
declare and assign all subsequent parameters in the function body so that
any non-idempotent parameters are evaluated in the correct order.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">for</span> param, i <span class="hljs-keyword">in</span> @params</pre></div></div>
            
        </li>
        
        
        <li id="section-256">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-256">&#x00a7;</a>
              </div>
              <p>Was <code>...</code> used with this parameter? Splat/expansion parameters cannot
have default values, so we need not worry about that.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> param.splat <span class="hljs-keyword">or</span> param <span class="hljs-keyword">instanceof</span> Expansion
        haveSplatParam = <span class="hljs-literal">yes</span>
        <span class="hljs-keyword">if</span> param.splat
          <span class="hljs-keyword">if</span> param.name <span class="hljs-keyword">instanceof</span> Arr <span class="hljs-keyword">or</span> param.name <span class="hljs-keyword">instanceof</span> Obj</pre></div></div>
            
        </li>
        
        
        <li id="section-257">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-257">&#x00a7;</a>
              </div>
              <p>Splat arrays are treated oddly by ES; deal with them the legacy
way in the function body. TODO: Should this be handled in the
function parameter list, and if so, how?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            splatParamName = o.scope.freeVariable <span class="hljs-string">&#x27;arg&#x27;</span>
            params.push ref = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> IdentifierLiteral splatParamName
            exprs.push <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(param.name), ref
          <span class="hljs-keyword">else</span>
            params.push ref = param.asReference o
            splatParamName = fragmentsToText ref.compileNodeWithoutComments o
          <span class="hljs-keyword">if</span> param.shouldCache()
            exprs.push <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(param.name), ref
        <span class="hljs-keyword">else</span> <span class="hljs-comment"># `param` is an Expansion</span>
          splatParamName = o.scope.freeVariable <span class="hljs-string">&#x27;args&#x27;</span>
          params.push <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> IdentifierLiteral splatParamName

        o.scope.parameter splatParamName</pre></div></div>
            
        </li>
        
        
        <li id="section-258">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-258">&#x00a7;</a>
              </div>
              <p>Parse all other parameters; if a splat paramater has not yet been
encountered, add these other parameters to the list to be output in
the function definition.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> param.shouldCache() <span class="hljs-keyword">or</span> haveBodyParam
          param.assignedInBody = <span class="hljs-literal">yes</span>
          haveBodyParam = <span class="hljs-literal">yes</span></pre></div></div>
            
        </li>
        
        
        <li id="section-259">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-259">&#x00a7;</a>
              </div>
              <p>This parameter cannot be declared or assigned in the parameter
list. So put a reference in the parameter list and add a statement
to the function body assigning it, e.g.
<code>(arg) =&gt; { var a = arg.a; }</code>, with a default value if it has one.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          <span class="hljs-keyword">if</span> param.value?
            condition = <span class="hljs-keyword">new</span> Op <span class="hljs-string">&#x27;===&#x27;</span>, param, <span class="hljs-keyword">new</span> UndefinedLiteral
            ifTrue = <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(param.name), param.value
            exprs.push <span class="hljs-keyword">new</span> If condition, ifTrue
          <span class="hljs-keyword">else</span>
            exprs.push <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(param.name), param.asReference(o), <span class="hljs-literal">null</span>, param: <span class="hljs-string">&#x27;alwaysDeclare&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-260">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-260">&#x00a7;</a>
              </div>
              <p>If this parameter comes before the splat or expansion, it will go
in the function definition parameter list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">unless</span> haveSplatParam</pre></div></div>
            
        </li>
        
        
        <li id="section-261">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-261">&#x00a7;</a>
              </div>
              <p>If this parameter has a default value, and it hasn’t already been
set by the <code>shouldCache()</code> block above, define it as a statement in
the function body. This parameter comes after the splat parameter,
so we can’t define its default value in the parameter list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          <span class="hljs-keyword">if</span> param.shouldCache()
            ref = param.asReference o
          <span class="hljs-keyword">else</span>
            <span class="hljs-keyword">if</span> param.value? <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> param.assignedInBody
              ref = <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(param.name), param.value, <span class="hljs-literal">null</span>, param: <span class="hljs-literal">yes</span>
            <span class="hljs-keyword">else</span>
              ref = param</pre></div></div>
            
        </li>
        
        
        <li id="section-262">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-262">&#x00a7;</a>
              </div>
              <p>Add this parameter’s reference(s) to the function scope.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          <span class="hljs-keyword">if</span> param.name <span class="hljs-keyword">instanceof</span> Arr <span class="hljs-keyword">or</span> param.name <span class="hljs-keyword">instanceof</span> Obj</pre></div></div>
            
        </li>
        
        
        <li id="section-263">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-263">&#x00a7;</a>
              </div>
              <p>This parameter is destructured.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            param.name.lhs = <span class="hljs-literal">yes</span>
            <span class="hljs-keyword">unless</span> param.shouldCache()
              param.name.eachName (prop) -&gt;
                o.scope.parameter prop.value
          <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-264">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-264">&#x00a7;</a>
              </div>
              <p>This compilation of the parameter is only to get its name to add
to the scope name tracking; since the compilation output here
isn’t kept for eventual output, don’t include comments in this
compilation, so that they get output the “real” time this param
is compiled.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            paramToAddToScope = <span class="hljs-keyword">if</span> param.value? <span class="hljs-keyword">then</span> param <span class="hljs-keyword">else</span> ref
            o.scope.parameter fragmentsToText paramToAddToScope.compileToFragmentsWithoutComments o
          params.push ref
        <span class="hljs-keyword">else</span>
          paramsAfterSplat.push param</pre></div></div>
            
        </li>
        
        
        <li id="section-265">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-265">&#x00a7;</a>
              </div>
              <p>If this parameter had a default value, since it’s no longer in the
function parameter list we need to assign its default value
(if necessary) as an expression in the body.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          <span class="hljs-keyword">if</span> param.value? <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> param.shouldCache()
            condition = <span class="hljs-keyword">new</span> Op <span class="hljs-string">&#x27;===&#x27;</span>, param, <span class="hljs-keyword">new</span> UndefinedLiteral
            ifTrue = <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(param.name), param.value
            exprs.push <span class="hljs-keyword">new</span> If condition, ifTrue</pre></div></div>
            
        </li>
        
        
        <li id="section-266">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-266">&#x00a7;</a>
              </div>
              <p>Add this parameter to the scope, since it wouldn’t have been added
yet since it was skipped earlier.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          o.scope.add param.name.value, <span class="hljs-string">&#x27;var&#x27;</span>, <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> param.name?.value?</pre></div></div>
            
        </li>
        
        
        <li id="section-267">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-267">&#x00a7;</a>
              </div>
              <p>If there were parameters after the splat or expansion parameter, those
parameters need to be assigned in the body of the function.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> paramsAfterSplat.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span></pre></div></div>
            
        </li>
        
        
        <li id="section-268">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-268">&#x00a7;</a>
              </div>
              <p>Create a destructured assignment, e.g. <code>[a, b, c] = [args..., b, c]</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      exprs.unshift <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(
          <span class="hljs-keyword">new</span> Arr [<span class="hljs-keyword">new</span> Splat(<span class="hljs-keyword">new</span> IdentifierLiteral(splatParamName)), (param.asReference o <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> paramsAfterSplat)...]
        ), <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> IdentifierLiteral splatParamName</pre></div></div>
            
        </li>
        
        
        <li id="section-269">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-269">&#x00a7;</a>
              </div>
              <p>Add new expressions to the function body</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    wasEmpty = @body.isEmpty()
    @disallowSuperInParamDefaults()
    @checkSuperCallsInConstructorBody()
    @body.expressions.unshift thisAssignments... <span class="hljs-keyword">unless</span> @expandCtorSuper thisAssignments
    @body.expressions.unshift exprs...
    <span class="hljs-keyword">if</span> @isMethod <span class="hljs-keyword">and</span> @bound <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @isStatic <span class="hljs-keyword">and</span> @classVariable
      boundMethodCheck = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal utility <span class="hljs-string">&#x27;boundMethodCheck&#x27;</span>, o
      @body.expressions.unshift <span class="hljs-keyword">new</span> Call(boundMethodCheck, [<span class="hljs-keyword">new</span> Value(<span class="hljs-keyword">new</span> ThisLiteral), @classVariable])
    @body.makeReturn() <span class="hljs-keyword">unless</span> wasEmpty <span class="hljs-keyword">or</span> @noReturn</pre></div></div>
            
        </li>
        
        
        <li id="section-270">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-270">&#x00a7;</a>
              </div>
              <p>JavaScript doesn’t allow bound (<code>=&gt;</code>) functions to also be generators.
This is usually caught via <code>Op::compileContinuation</code>, but double-check:</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @bound <span class="hljs-keyword">and</span> @isGenerator
      yieldNode = @body.contains (node) -&gt; node <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> node.operator <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;yield&#x27;</span>
      (yieldNode <span class="hljs-keyword">or</span> @).error <span class="hljs-string">&#x27;yield cannot occur inside bound (fat arrow) functions&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-271">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-271">&#x00a7;</a>
              </div>
              <p>Assemble the output</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    modifiers = []
    modifiers.push <span class="hljs-string">&#x27;static&#x27;</span> <span class="hljs-keyword">if</span> @isMethod <span class="hljs-keyword">and</span> @isStatic
    modifiers.push <span class="hljs-string">&#x27;async&#x27;</span>  <span class="hljs-keyword">if</span> @isAsync
    <span class="hljs-keyword">unless</span> @isMethod <span class="hljs-keyword">or</span> @bound
      modifiers.push <span class="hljs-string">&quot;function<span class="hljs-subst">#{<span class="hljs-keyword">if</span> @isGenerator <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;*&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>}</span>&quot;</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @isGenerator
      modifiers.push <span class="hljs-string">&#x27;*&#x27;</span>

    signature = [@makeCode <span class="hljs-string">&#x27;(&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-272">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-272">&#x00a7;</a>
              </div>
              <p>Block comments between a function name and <code>(</code> get output between
<code>function</code> and <code>(</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @paramStart?.comments?
      @compileCommentFragments o, @paramStart, signature
    <span class="hljs-keyword">for</span> param, i <span class="hljs-keyword">in</span> params
      signature.push @makeCode <span class="hljs-string">&#x27;, &#x27;</span> <span class="hljs-keyword">if</span> i <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
      signature.push @makeCode <span class="hljs-string">&#x27;...&#x27;</span> <span class="hljs-keyword">if</span> haveSplatParam <span class="hljs-keyword">and</span> i <span class="hljs-keyword">is</span> params.length - <span class="hljs-number">1</span></pre></div></div>
            
        </li>
        
        
        <li id="section-273">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-273">&#x00a7;</a>
              </div>
              <p>Compile this parameter, but if any generated variables get created
(e.g. <code>ref</code>), shift those into the parent scope since we can’t put a
<code>var</code> line inside a function parameter list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      scopeVariablesCount = o.scope.variables.length
      signature.push param.compileToFragments(o, LEVEL_PAREN)...
      <span class="hljs-keyword">if</span> scopeVariablesCount <span class="hljs-keyword">isnt</span> o.scope.variables.length
        generatedVariables = o.scope.variables.splice scopeVariablesCount
        o.scope.parent.variables.push generatedVariables...
    signature.push @makeCode <span class="hljs-string">&#x27;)&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-274">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-274">&#x00a7;</a>
              </div>
              <p>Block comments between <code>)</code> and <code>-&gt;</code>/<code>=&gt;</code> get output between <code>)</code> and <code>{</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @funcGlyph?.comments?
      comment.unshift = <span class="hljs-literal">no</span> <span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> @funcGlyph.comments
      @compileCommentFragments o, @funcGlyph, signature

    body = @body.compileWithDeclarations o <span class="hljs-keyword">unless</span> @body.isEmpty()</pre></div></div>
            
        </li>
        
        
        <li id="section-275">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-275">&#x00a7;</a>
              </div>
              <p>We need to compile the body before method names to ensure <code>super</code>
references are handled.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> @isMethod
      [methodScope, o.scope] = [o.scope, o.scope.parent]
      name = @name.compileToFragments o
      name.shift() <span class="hljs-keyword">if</span> name[<span class="hljs-number">0</span>].code <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;.&#x27;</span>
      o.scope = methodScope

    answer = @joinFragmentArrays (@makeCode m <span class="hljs-keyword">for</span> m <span class="hljs-keyword">in</span> modifiers), <span class="hljs-string">&#x27; &#x27;</span>
    answer.push @makeCode <span class="hljs-string">&#x27; &#x27;</span> <span class="hljs-keyword">if</span> modifiers.length <span class="hljs-keyword">and</span> name
    answer.push name... <span class="hljs-keyword">if</span> name
    answer.push signature...
    answer.push @makeCode <span class="hljs-string">&#x27; =&gt;&#x27;</span> <span class="hljs-keyword">if</span> @bound <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @isMethod
    answer.push @makeCode <span class="hljs-string">&#x27; {&#x27;</span>
    answer.push @makeCode(<span class="hljs-string">&#x27;\n&#x27;</span>), body..., @makeCode(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>&quot;</span>) <span class="hljs-keyword">if</span> body?.length
    answer.push @makeCode <span class="hljs-string">&#x27;}&#x27;</span>

    <span class="hljs-keyword">return</span> indentInitial answer, @ <span class="hljs-keyword">if</span> @isMethod
    <span class="hljs-keyword">if</span> @front <span class="hljs-keyword">or</span> (o.level &gt;= LEVEL_ACCESS) <span class="hljs-keyword">then</span> @wrapInParentheses answer <span class="hljs-keyword">else</span> answer

  updateOptions: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.scope         = del(o, <span class="hljs-string">&#x27;classScope&#x27;</span>) <span class="hljs-keyword">or</span> @makeScope o.scope
    o.scope.shared  = del(o, <span class="hljs-string">&#x27;sharedScope&#x27;</span>)
    o.indent        += TAB
    <span class="hljs-keyword">delete</span> o.bare
    <span class="hljs-keyword">delete</span> o.isExistentialEquals

  checkForDuplicateParams: <span class="hljs-function">-&gt;</span>
    paramNames = []
    @eachParamName (name, node, param) -&gt;
      node.error <span class="hljs-string">&quot;multiple parameters named &#x27;<span class="hljs-subst">#{name}</span>&#x27;&quot;</span> <span class="hljs-keyword">if</span> name <span class="hljs-keyword">in</span> paramNames
      paramNames.push name

  eachParamName: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span>
    param.eachName iterator <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> @params</pre></div></div>
            
        </li>
        
        
        <li id="section-276">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-276">&#x00a7;</a>
              </div>
              <p>Short-circuit <code>traverseChildren</code> method to prevent it from crossing scope
boundaries unless <code>crossScope</code> is <code>true</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  traverseChildren: <span class="hljs-function"><span class="hljs-params">(crossScope, func)</span> -&gt;</span>
    super(crossScope, func) <span class="hljs-keyword">if</span> crossScope</pre></div></div>
            
        </li>
        
        
        <li id="section-277">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-277">&#x00a7;</a>
              </div>
              <p>Short-circuit <code>replaceInContext</code> method to prevent it from crossing context boundaries. Bound
functions have the same context.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  replaceInContext: <span class="hljs-function"><span class="hljs-params">(child, replacement)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @bound
      super child, replacement
    <span class="hljs-keyword">else</span>
      <span class="hljs-literal">false</span>

  disallowSuperInParamDefaults: <span class="hljs-function"><span class="hljs-params">({forAst} = {})</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> <span class="hljs-keyword">unless</span> @ctor

    @eachSuperCall Block.wrap(@params), <span class="hljs-function"><span class="hljs-params">(superCall)</span> -&gt;</span>
      superCall.error <span class="hljs-string">&quot;&#x27;super&#x27; is not allowed in constructor parameter defaults&quot;</span>
    , checkForThisBeforeSuper: <span class="hljs-keyword">not</span> forAst

  checkSuperCallsInConstructorBody: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> <span class="hljs-keyword">unless</span> @ctor

    seenSuper = @eachSuperCall @body, <span class="hljs-function"><span class="hljs-params">(superCall)</span> =&gt;</span>
      superCall.error <span class="hljs-string">&quot;&#x27;super&#x27; is only allowed in derived class constructors&quot;</span> <span class="hljs-keyword">if</span> @ctor <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;base&#x27;</span>

    seenSuper

  flagThisParamInDerivedClassConstructorWithoutCallingSuper: <span class="hljs-function"><span class="hljs-params">(param)</span> -&gt;</span>
    param.error <span class="hljs-string">&quot;Can&#x27;t use @params in derived class constructors without calling super&quot;</span>

  checkForAsyncOrGeneratorConstructor: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @ctor
      @name.error <span class="hljs-string">&#x27;Class constructor may not be async&#x27;</span>       <span class="hljs-keyword">if</span> @isAsync
      @name.error <span class="hljs-string">&#x27;Class constructor may not be a generator&#x27;</span> <span class="hljs-keyword">if</span> @isGenerator

  disallowLoneExpansionAndMultipleSplats: <span class="hljs-function">-&gt;</span>
    seenSplatParam = <span class="hljs-literal">no</span>
    <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> @params</pre></div></div>
            
        </li>
        
        
        <li id="section-278">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-278">&#x00a7;</a>
              </div>
              <p>Was <code>...</code> used with this parameter? (Only one such parameter is allowed
per function.)</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> param.splat <span class="hljs-keyword">or</span> param <span class="hljs-keyword">instanceof</span> Expansion
        <span class="hljs-keyword">if</span> seenSplatParam
          param.error <span class="hljs-string">&#x27;only one splat or expansion parameter is allowed per function definition&#x27;</span>
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> param <span class="hljs-keyword">instanceof</span> Expansion <span class="hljs-keyword">and</span> @params.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
          param.error <span class="hljs-string">&#x27;an expansion parameter cannot be the only parameter in a function definition&#x27;</span>
        seenSplatParam = <span class="hljs-literal">yes</span>

  expandCtorSuper: <span class="hljs-function"><span class="hljs-params">(thisAssignments)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> <span class="hljs-keyword">unless</span> @ctor

    seenSuper = @eachSuperCall @body, <span class="hljs-function"><span class="hljs-params">(superCall)</span> =&gt;</span>
      superCall.expressions = thisAssignments

    haveThisParam = thisAssignments.length <span class="hljs-keyword">and</span> thisAssignments.length <span class="hljs-keyword">isnt</span> @thisAssignments?.length
    <span class="hljs-keyword">if</span> @ctor <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;derived&#x27;</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> seenSuper <span class="hljs-keyword">and</span> haveThisParam
      param = thisAssignments[<span class="hljs-number">0</span>].variable
      @flagThisParamInDerivedClassConstructorWithoutCallingSuper param

    seenSuper</pre></div></div>
            
        </li>
        
        
        <li id="section-279">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-279">&#x00a7;</a>
              </div>
              <p>Find all super calls in the given context node;
returns <code>true</code> if <code>iterator</code> is called.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  eachSuperCall: <span class="hljs-function"><span class="hljs-params">(context, iterator, {checkForThisBeforeSuper = <span class="hljs-literal">yes</span>} = {})</span> -&gt;</span>
    seenSuper = <span class="hljs-literal">no</span>

    context.traverseChildren <span class="hljs-literal">yes</span>, <span class="hljs-function"><span class="hljs-params">(child)</span> =&gt;</span>
      <span class="hljs-keyword">if</span> child <span class="hljs-keyword">instanceof</span> SuperCall</pre></div></div>
            
        </li>
        
        
        <li id="section-280">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-280">&#x00a7;</a>
              </div>
              <p><code>super</code> in a constructor (the only <code>super</code> without an accessor)
cannot be given an argument with a reference to <code>this</code>, as that would
be referencing <code>this</code> before calling <code>super</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">unless</span> child.variable.accessor
          childArgs = child.args.filter (arg) -&gt;
            arg <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Class <span class="hljs-keyword">and</span> (arg <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">or</span> arg.bound)
          Block.wrap(childArgs).traverseChildren <span class="hljs-literal">yes</span>, <span class="hljs-function"><span class="hljs-params">(node)</span> =&gt;</span>
            node.error <span class="hljs-string">&quot;Can&#x27;t call super with @params in derived class constructors&quot;</span> <span class="hljs-keyword">if</span> node.this
        seenSuper = <span class="hljs-literal">yes</span>
        iterator child
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> checkForThisBeforeSuper <span class="hljs-keyword">and</span> child <span class="hljs-keyword">instanceof</span> ThisLiteral <span class="hljs-keyword">and</span> @ctor <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;derived&#x27;</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> seenSuper
        child.error <span class="hljs-string">&quot;Can&#x27;t reference &#x27;this&#x27; before calling super in derived class constructors&quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-281">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-281">&#x00a7;</a>
              </div>
              <p><code>super</code> has the same target in bound (arrow) functions, so check them too</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      child <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> SuperCall <span class="hljs-keyword">and</span> (child <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">or</span> child.bound)

    seenSuper

  propagateLhs: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> @params
      {name} = param
      <span class="hljs-keyword">if</span> name <span class="hljs-keyword">instanceof</span> Arr <span class="hljs-keyword">or</span> name <span class="hljs-keyword">instanceof</span> Obj
        name.propagateLhs <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> param <span class="hljs-keyword">instanceof</span> Expansion
        param.lhs = <span class="hljs-literal">yes</span>

  astAddParamsToScope: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @eachParamName (name) -&gt;
      o.scope.add name, <span class="hljs-string">&#x27;param&#x27;</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @updateOptions o
    @checkForAsyncOrGeneratorConstructor()
    @checkForDuplicateParams()
    @disallowSuperInParamDefaults forAst: <span class="hljs-literal">yes</span>
    @disallowLoneExpansionAndMultipleSplats()
    seenSuper = @checkSuperCallsInConstructorBody()
    <span class="hljs-keyword">if</span> @ctor <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;derived&#x27;</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> seenSuper
      @eachParamName (name, node) =&gt;
        <span class="hljs-keyword">if</span> node.this
          @flagThisParamInDerivedClassConstructorWithoutCallingSuper node
    @astAddParamsToScope o
    @body.makeReturn <span class="hljs-literal">null</span>, <span class="hljs-literal">yes</span> <span class="hljs-keyword">unless</span> @body.isEmpty() <span class="hljs-keyword">or</span> @noReturn

    super o

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isMethod
      <span class="hljs-string">&#x27;ClassMethod&#x27;</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @bound
      <span class="hljs-string">&#x27;ArrowFunctionExpression&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;FunctionExpression&#x27;</span>

  paramForAst: <span class="hljs-function"><span class="hljs-params">(param)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> param <span class="hljs-keyword">if</span> param <span class="hljs-keyword">instanceof</span> Expansion
    {name, value, splat} = param
    <span class="hljs-keyword">if</span> splat
      <span class="hljs-keyword">new</span> Splat name, lhs: <span class="hljs-literal">yes</span>, postfix: splat.postfix
      .withLocationDataFrom param
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> value?
      <span class="hljs-keyword">new</span> Assign name, value, <span class="hljs-literal">null</span>, param: <span class="hljs-literal">yes</span>
      .withLocationDataFrom locationData: mergeLocationData name.locationData, value.locationData
    <span class="hljs-keyword">else</span>
      name

  methodAstProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
<span class="hljs-function">    <span class="hljs-title">getIsComputed</span> = =&gt;</span>
      <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @name <span class="hljs-keyword">instanceof</span> Index
      <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @name <span class="hljs-keyword">instanceof</span> ComputedPropertyName
      <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @name.name <span class="hljs-keyword">instanceof</span> ComputedPropertyName
      <span class="hljs-literal">no</span>

    <span class="hljs-keyword">return</span>
      static: !!@isStatic
      key: @name.ast o
      computed: getIsComputed()
      kind:
        <span class="hljs-keyword">if</span> @ctor
          <span class="hljs-string">&#x27;constructor&#x27;</span>
        <span class="hljs-keyword">else</span>
          <span class="hljs-string">&#x27;method&#x27;</span>
      operator: @operatorToken?.value ? <span class="hljs-string">&#x27;=&#x27;</span>
      staticClassName: @isStatic.staticClassName?.ast(o) ? <span class="hljs-literal">null</span>
      bound: !!@bound

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.assign
      params: @paramForAst(param).ast(o) <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> @params
      body: @body.ast (<span class="hljs-built_in">Object</span>.assign {}, o, checkForDirectives: <span class="hljs-literal">yes</span>), LEVEL_TOP
      generator: !!@isGenerator
      async: !!@isAsync</pre></div></div>
            
        </li>
        
        
        <li id="section-282">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-282">&#x00a7;</a>
              </div>
              <p>We never generate named functions, so specify <code>id</code> as <code>null</code>, which
matches the Babel AST for anonymous function expressions/arrow functions</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      id: <span class="hljs-literal">null</span>
      hasIndentedBody: @body.locationData.first_line &gt; @funcGlyph?.locationData.first_line
    ,
      <span class="hljs-keyword">if</span> @isMethod <span class="hljs-keyword">then</span> @methodAstProperties o <span class="hljs-keyword">else</span> {}

  astLocationData: <span class="hljs-function">-&gt;</span>
    functionLocationData = super()
    <span class="hljs-keyword">return</span> functionLocationData <span class="hljs-keyword">unless</span> @isMethod

    astLocationData = mergeAstLocationData @name.astLocationData(), functionLocationData
    <span class="hljs-keyword">if</span> @isStatic.staticClassName?
      astLocationData = mergeAstLocationData @isStatic.staticClassName.astLocationData(), astLocationData
    astLocationData</pre></div></div>
            
        </li>
        
        
        <li id="section-283">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-283">&#x00a7;</a>
              </div>
              <h3 id="param">Param</h3>

            </div>
            
        </li>
        
        
        <li id="section-284">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-284">&#x00a7;</a>
              </div>
              <p>A parameter in a function definition. Beyond a typical JavaScript parameter,
these parameters can also attach themselves to the context of the function,
as well as be a splat, gathering up a group of parameters into an array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Param = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Param</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@name, @value, @splat)</span> -&gt;</span>
    super()

    message = isUnassignable @name.unwrapAll().value
    @name.error message <span class="hljs-keyword">if</span> message
    <span class="hljs-keyword">if</span> @name <span class="hljs-keyword">instanceof</span> Obj <span class="hljs-keyword">and</span> @name.generated
      token = @name.objects[<span class="hljs-number">0</span>].operatorToken
      token.error <span class="hljs-string">&quot;unexpected <span class="hljs-subst">#{token.value}</span>&quot;</span>

  children: [<span class="hljs-string">&#x27;name&#x27;</span>, <span class="hljs-string">&#x27;value&#x27;</span>]

  compileToFragments: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @name.compileToFragments o, LEVEL_LIST

  compileToFragmentsWithoutComments: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @name.compileToFragmentsWithoutComments o, LEVEL_LIST

  asReference: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> @reference <span class="hljs-keyword">if</span> @reference
    node = @name
    <span class="hljs-keyword">if</span> node.this
      name = node.properties[<span class="hljs-number">0</span>].name.value
      name = <span class="hljs-string">&quot;_<span class="hljs-subst">#{name}</span>&quot;</span> <span class="hljs-keyword">if</span> name <span class="hljs-keyword">in</span> JS_FORBIDDEN
      node = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable name
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node.shouldCache()
      node = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;arg&#x27;</span>
    node = <span class="hljs-keyword">new</span> Value node
    node.updateLocationDataIfMissing @locationData
    @reference = node

  shouldCache: <span class="hljs-function">-&gt;</span>
    @name.shouldCache()</pre></div></div>
            
        </li>
        
        
        <li id="section-285">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-285">&#x00a7;</a>
              </div>
              <p>Iterates the name or names of a <code>Param</code>.
In a sense, a destructured parameter represents multiple JS parameters. This
method allows to iterate them all.
The <code>iterator</code> function will be called as <code>iterator(name, node)</code> where
<code>name</code> is the name of the parameter and <code>node</code> is the AST node corresponding
to that name.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  eachName: <span class="hljs-function"><span class="hljs-params">(iterator, name = @name)</span> -&gt;</span>
<span class="hljs-function">    <span class="hljs-title">checkAssignabilityOfLiteral</span> = <span class="hljs-params">(literal)</span> -&gt;</span>
      message = isUnassignable literal.value
      <span class="hljs-keyword">if</span> message
        literal.error message
      <span class="hljs-keyword">unless</span> literal.isAssignable()
        literal.error <span class="hljs-string">&quot;&#x27;<span class="hljs-subst">#{literal.value}</span>&#x27; can&#x27;t be assigned&quot;</span>
<span class="hljs-function">
    <span class="hljs-title">atParam</span> = <span class="hljs-params">(obj, originalObj = <span class="hljs-literal">null</span>)</span> =&gt;</span> iterator <span class="hljs-string">&quot;@<span class="hljs-subst">#{obj.properties[<span class="hljs-number">0</span>].name.value}</span>&quot;</span>, obj, @, originalObj
    <span class="hljs-keyword">if</span> name <span class="hljs-keyword">instanceof</span> Call
      name.error <span class="hljs-string">&quot;Function invocation can&#x27;t be assigned&quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-286">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-286">&#x00a7;</a>
              </div>
              <ul>
<li>simple literals <code>foo</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> name <span class="hljs-keyword">instanceof</span> Literal
      checkAssignabilityOfLiteral name
      <span class="hljs-keyword">return</span> iterator name.value, name, @</pre></div></div>
            
        </li>
        
        
        <li id="section-287">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-287">&#x00a7;</a>
              </div>
              <ul>
<li>at-params <code>@foo</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">return</span> atParam name <span class="hljs-keyword">if</span> name <span class="hljs-keyword">instanceof</span> Value
    <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> name.objects ? []</pre></div></div>
            
        </li>
        
        
        <li id="section-288">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-288">&#x00a7;</a>
              </div>
              <p>Save original obj.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      nObj = obj</pre></div></div>
            
        </li>
        
        
        <li id="section-289">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-289">&#x00a7;</a>
              </div>
              <ul>
<li>destructured parameter with default value</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> obj.context?
        obj = obj.variable</pre></div></div>
            
        </li>
        
        
        <li id="section-290">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-290">&#x00a7;</a>
              </div>
              <ul>
<li>assignments within destructured parameters <code>{foo:bar}</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign</pre></div></div>
            
        </li>
        
        
        <li id="section-291">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-291">&#x00a7;</a>
              </div>
              <p>… possibly with a default value</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">if</span> obj.value <span class="hljs-keyword">instanceof</span> Assign
          obj = obj.value.variable
        <span class="hljs-keyword">else</span>
          obj = obj.value
        @eachName iterator, obj.unwrap()</pre></div></div>
            
        </li>
        
        
        <li id="section-292">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-292">&#x00a7;</a>
              </div>
              <ul>
<li>splats within destructured parameters <code>[xs...]</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Splat
        node = obj.name.unwrap()
        iterator node.value, node, @
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Value</pre></div></div>
            
        </li>
        
        
        <li id="section-293">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-293">&#x00a7;</a>
              </div>
              <ul>
<li>destructured parameters within destructured parameters <code>[{a}]</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">if</span> obj.isArray() <span class="hljs-keyword">or</span> obj.isObject()
          @eachName iterator, obj.base</pre></div></div>
            
        </li>
        
        
        <li id="section-294">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-294">&#x00a7;</a>
              </div>
              <ul>
<li>at-params within destructured parameters <code>{@foo}</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj.this
          atParam obj, nObj</pre></div></div>
            
        </li>
        
        
        <li id="section-295">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-295">&#x00a7;</a>
              </div>
              <ul>
<li>simple destructured parameters {foo}</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">else</span>
          checkAssignabilityOfLiteral obj.base
          iterator obj.base.value, obj.base, @
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Elision
        obj
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Expansion
        obj.error <span class="hljs-string">&quot;illegal parameter <span class="hljs-subst">#{obj.compile()}</span>&quot;</span>
    <span class="hljs-keyword">return</span></pre></div></div>
            
        </li>
        
        
        <li id="section-296">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-296">&#x00a7;</a>
              </div>
              <p>Rename a param by replacing the given AST node for a name with a new node.
This needs to ensure that the the source for object destructuring does not change.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  renameParam: <span class="hljs-function"><span class="hljs-params">(node, newNode)</span> -&gt;</span>
<span class="hljs-function">    <span class="hljs-title">isNode</span>      = <span class="hljs-params">(candidate)</span> -&gt;</span> candidate <span class="hljs-keyword">is</span> node
<span class="hljs-function">    <span class="hljs-title">replacement</span> = <span class="hljs-params">(node, parent)</span> =&gt;</span>
      <span class="hljs-keyword">if</span> parent <span class="hljs-keyword">instanceof</span> Obj
        key = node
        key = node.properties[<span class="hljs-number">0</span>].name <span class="hljs-keyword">if</span> node.this</pre></div></div>
            
        </li>
        
        
        <li id="section-297">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-297">&#x00a7;</a>
              </div>
              <p>No need to assign a new variable for the destructured variable if the variable isn’t reserved.
Examples:
<code>({@foo}) -&gt;</code>  should compile to <code>({foo}) { this.foo = foo}</code>
<code>foo = 1; ({@foo}) -&gt;</code> should compile to <code>foo = 1; ({foo:foo1}) { this.foo = foo1 }</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">if</span> node.this <span class="hljs-keyword">and</span> key.value <span class="hljs-keyword">is</span> newNode.value
          <span class="hljs-keyword">new</span> Value newNode
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(key), newNode, <span class="hljs-string">&#x27;object&#x27;</span>
      <span class="hljs-keyword">else</span>
        newNode

    @replaceInContext isNode, replacement</pre></div></div>
            
        </li>
        
        
        <li id="section-298">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-298">&#x00a7;</a>
              </div>
              <h3 id="splat">Splat</h3>

            </div>
            
        </li>
        
        
        <li id="section-299">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-299">&#x00a7;</a>
              </div>
              <p>A splat, either as a parameter to a function, an argument to a call,
or as part of a destructuring assignment.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Splat = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Splat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(name, {@lhs, @postfix = <span class="hljs-literal">true</span>} = {})</span> -&gt;</span>
    super()
    @name = <span class="hljs-keyword">if</span> name.compile <span class="hljs-keyword">then</span> name <span class="hljs-keyword">else</span> <span class="hljs-keyword">new</span> Literal name

  children: [<span class="hljs-string">&#x27;name&#x27;</span>]

  shouldCache: <span class="hljs-function">-&gt;</span> <span class="hljs-literal">no</span>

  isAssignable: <span class="hljs-function"><span class="hljs-params">({allowComplexSplat = <span class="hljs-literal">no</span>} = {})</span>-&gt;</span>
    <span class="hljs-keyword">return</span> allowComplexSplat <span class="hljs-keyword">if</span> @name <span class="hljs-keyword">instanceof</span> Obj <span class="hljs-keyword">or</span> @name <span class="hljs-keyword">instanceof</span> Parens
    @name.isAssignable() <span class="hljs-keyword">and</span> (<span class="hljs-keyword">not</span> @name.isAtomic <span class="hljs-keyword">or</span> @name.isAtomic())

  assigns: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    @name.assigns name

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    compiledSplat = [@makeCode(<span class="hljs-string">&#x27;...&#x27;</span>), @name.compileToFragments(o, LEVEL_OP)...]
    <span class="hljs-keyword">return</span> compiledSplat <span class="hljs-keyword">unless</span> @jsx
    <span class="hljs-keyword">return</span> [@makeCode(<span class="hljs-string">&#x27;{&#x27;</span>), compiledSplat..., @makeCode(<span class="hljs-string">&#x27;}&#x27;</span>)]

  unwrap: <span class="hljs-function">-&gt;</span> @name

  propagateLhs: <span class="hljs-function"><span class="hljs-params">(setLhs)</span> -&gt;</span>
    @lhs = <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> setLhs
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> @lhs
    @name.propagateLhs? <span class="hljs-literal">yes</span>

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @jsx
      <span class="hljs-string">&#x27;JSXSpreadAttribute&#x27;</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @lhs
      <span class="hljs-string">&#x27;RestElement&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;SpreadElement&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> {
    argument: @name.ast o, LEVEL_OP
    @postfix
  }</pre></div></div>
            
        </li>
        
        
        <li id="section-300">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-300">&#x00a7;</a>
              </div>
              <h3 id="expansion">Expansion</h3>

            </div>
            
        </li>
        
        
        <li id="section-301">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-301">&#x00a7;</a>
              </div>
              <p>Used to skip values inside an array destructuring (pattern matching) or
parameter list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Expansion = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Expansion</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

  shouldCache: NO

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @throwLhsError()

  asReference: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    this

  eachName: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span>

  throwLhsError: <span class="hljs-function">-&gt;</span>
    @error <span class="hljs-string">&#x27;Expansion must be used inside a destructuring assignment or parameter list&#x27;</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">unless</span> @lhs
      @throwLhsError()

    super o

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;RestElement&#x27;</span>

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      argument: <span class="hljs-literal">null</span></pre></div></div>
            
        </li>
        
        
        <li id="section-302">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-302">&#x00a7;</a>
              </div>
              <h3 id="elision">Elision</h3>

            </div>
            
        </li>
        
        
        <li id="section-303">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-303">&#x00a7;</a>
              </div>
              <p>Array elision element (for example, [,a, , , b, , c, ,]).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Elision = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Elision</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

  isAssignable: YES

  shouldCache: NO

  compileToFragments: <span class="hljs-function"><span class="hljs-params">(o, level)</span> -&gt;</span>
    fragment = super o, level
    fragment.isElision = <span class="hljs-literal">yes</span>
    fragment

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [@makeCode <span class="hljs-string">&#x27;, &#x27;</span>]

  asReference: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    this

  eachName: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span>

  astNode: <span class="hljs-function">-&gt;</span>
    <span class="hljs-literal">null</span></pre></div></div>
            
        </li>
        
        
        <li id="section-304">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-304">&#x00a7;</a>
              </div>
              <h3 id="while">While</h3>

            </div>
            
        </li>
        
        
        <li id="section-305">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-305">&#x00a7;</a>
              </div>
              <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
it, all other loops can be manufactured. Useful in cases where you need more
flexibility or more speed than a comprehension can provide.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.While = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">While</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@condition, {invert: @inverted, @guard, @isLoop} = {})</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;condition&#x27;</span>, <span class="hljs-string">&#x27;guard&#x27;</span>, <span class="hljs-string">&#x27;body&#x27;</span>]

  isStatement: YES

  makeReturn: <span class="hljs-function"><span class="hljs-params">(results, mark)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> super(results, mark) <span class="hljs-keyword">if</span> results
    @returns = <span class="hljs-keyword">not</span> @jumps()
    <span class="hljs-keyword">if</span> mark
      @body.makeReturn(results, mark) <span class="hljs-keyword">if</span> @returns
      <span class="hljs-keyword">return</span>
    this

  addBody: <span class="hljs-function"><span class="hljs-params">(@body)</span> -&gt;</span>
    this

  jumps: <span class="hljs-function">-&gt;</span>
    {expressions} = @body
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> expressions.length
    <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> expressions
      <span class="hljs-keyword">return</span> jumpNode <span class="hljs-keyword">if</span> jumpNode = node.jumps loop: <span class="hljs-literal">yes</span>
    <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-306">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-306">&#x00a7;</a>
              </div>
              <p>The main difference from a JavaScript <em>while</em> is that the CoffeeScript
<em>while</em> can be used as a part of a larger expression – while loops may
return an array containing the computed result of each iteration.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.indent += TAB
    set      = <span class="hljs-string">&#x27;&#x27;</span>
    {body}   = this
    <span class="hljs-keyword">if</span> body.isEmpty()
      body = @makeCode <span class="hljs-string">&#x27;&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">if</span> @returns
        body.makeReturn rvar = o.scope.freeVariable <span class="hljs-string">&#x27;results&#x27;</span>
        set  = <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span><span class="hljs-subst">#{rvar}</span> = [];\n&quot;</span>
      <span class="hljs-keyword">if</span> @guard
        <span class="hljs-keyword">if</span> body.expressions.length &gt; <span class="hljs-number">1</span>
          body.expressions.unshift <span class="hljs-keyword">new</span> If (<span class="hljs-keyword">new</span> Parens @guard).invert(), <span class="hljs-keyword">new</span> StatementLiteral <span class="hljs-string">&quot;continue&quot;</span>
        <span class="hljs-keyword">else</span>
          body = Block.wrap [<span class="hljs-keyword">new</span> If @guard, body] <span class="hljs-keyword">if</span> @guard
      body = [].concat @makeCode(<span class="hljs-string">&quot;\n&quot;</span>), (body.compileToFragments o, LEVEL_TOP), @makeCode(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>&quot;</span>)
    answer = [].concat @makeCode(set + @tab + <span class="hljs-string">&quot;while (&quot;</span>), @processedCondition().compileToFragments(o, LEVEL_PAREN),
      @makeCode(<span class="hljs-string">&quot;) {&quot;</span>), body, @makeCode(<span class="hljs-string">&quot;}&quot;</span>)
    <span class="hljs-keyword">if</span> @returns
      answer.push @makeCode <span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>return <span class="hljs-subst">#{rvar}</span>;&quot;</span>
    answer

  processedCondition: <span class="hljs-function">-&gt;</span>
    @processedConditionCache ?= <span class="hljs-keyword">if</span> @inverted <span class="hljs-keyword">then</span> @condition.invert() <span class="hljs-keyword">else</span> @condition

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;WhileStatement&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      test: @condition.ast o, LEVEL_PAREN
      body: @body.ast o, LEVEL_TOP
      guard: @guard?.ast(o) ? <span class="hljs-literal">null</span>
      inverted: !!@inverted
      postfix: !!@postfix
      loop: !!@isLoop</pre></div></div>
            
        </li>
        
        
        <li id="section-307">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-307">&#x00a7;</a>
              </div>
              <h3 id="op">Op</h3>

            </div>
            
        </li>
        
        
        <li id="section-308">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-308">&#x00a7;</a>
              </div>
              <p>Simple Arithmetic and logical operations. Performs some conversion from
CoffeeScript operations into their JavaScript equivalents.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Op = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Op</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(op, first, second, flip, {@invertOperator, @originalOperator = op} = {})</span> -&gt;</span>
    super()

    <span class="hljs-keyword">if</span> op <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;new&#x27;</span>
      <span class="hljs-keyword">if</span> ((firstCall = unwrapped = first.unwrap()) <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">or</span> (firstCall = unwrapped.base) <span class="hljs-keyword">instanceof</span> Call) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> firstCall.<span class="hljs-keyword">do</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> firstCall.isNew
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Value firstCall.newInstance(), <span class="hljs-keyword">if</span> firstCall <span class="hljs-keyword">is</span> unwrapped <span class="hljs-keyword">then</span> [] <span class="hljs-keyword">else</span> unwrapped.properties
      first = <span class="hljs-keyword">new</span> Parens first <span class="hljs-keyword">unless</span> first <span class="hljs-keyword">instanceof</span> Parens <span class="hljs-keyword">or</span> first.unwrap() <span class="hljs-keyword">instanceof</span> IdentifierLiteral <span class="hljs-keyword">or</span> first.hasProperties?()
      call = <span class="hljs-keyword">new</span> Call first, []
      call.locationData = @locationData
      call.isNew = <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">return</span> call

    @operator = CONVERSIONS[op] <span class="hljs-keyword">or</span> op
    @first    = first
    @second   = second
    @flip     = !!flip

    <span class="hljs-keyword">if</span> @operator <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;--&#x27;</span>, <span class="hljs-string">&#x27;++&#x27;</span>]
      message = isUnassignable @first.unwrapAll().value
      @first.error message <span class="hljs-keyword">if</span> message

    <span class="hljs-keyword">return</span> this</pre></div></div>
            
        </li>
        
        
        <li id="section-309">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-309">&#x00a7;</a>
              </div>
              <p>The map of conversions from CoffeeScript to JavaScript symbols.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  CONVERSIONS =
    <span class="hljs-string">&#x27;==&#x27;</span>:        <span class="hljs-string">&#x27;===&#x27;</span>
    <span class="hljs-string">&#x27;!=&#x27;</span>:        <span class="hljs-string">&#x27;!==&#x27;</span>
    <span class="hljs-string">&#x27;of&#x27;</span>:        <span class="hljs-string">&#x27;in&#x27;</span>
    <span class="hljs-string">&#x27;yieldfrom&#x27;</span>: <span class="hljs-string">&#x27;yield*&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-310">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-310">&#x00a7;</a>
              </div>
              <p>The map of invertible operators.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  INVERSIONS =
    <span class="hljs-string">&#x27;!==&#x27;</span>: <span class="hljs-string">&#x27;===&#x27;</span>
    <span class="hljs-string">&#x27;===&#x27;</span>: <span class="hljs-string">&#x27;!==&#x27;</span>

  children: [<span class="hljs-string">&#x27;first&#x27;</span>, <span class="hljs-string">&#x27;second&#x27;</span>]

  isNumber: <span class="hljs-function">-&gt;</span>
    @isUnary() <span class="hljs-keyword">and</span> @operator <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;+&#x27;</span>, <span class="hljs-string">&#x27;-&#x27;</span>] <span class="hljs-keyword">and</span>
      @first <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> @first.isNumber()

  isAwait: <span class="hljs-function">-&gt;</span>
    @operator <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;await&#x27;</span>

  isYield: <span class="hljs-function">-&gt;</span>
    @operator <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;yield&#x27;</span>, <span class="hljs-string">&#x27;yield*&#x27;</span>]

  isUnary: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">not</span> @second

  shouldCache: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">not</span> @isNumber()</pre></div></div>
            
        </li>
        
        
        <li id="section-311">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-311">&#x00a7;</a>
              </div>
              <p>Am I capable of
<a href="https://docs.python.org/3/reference/expressions.html#not-in">Python-style comparison chaining</a>?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  isChainable: <span class="hljs-function">-&gt;</span>
    @operator <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;&lt;&#x27;</span>, <span class="hljs-string">&#x27;&gt;&#x27;</span>, <span class="hljs-string">&#x27;&gt;=&#x27;</span>, <span class="hljs-string">&#x27;&lt;=&#x27;</span>, <span class="hljs-string">&#x27;===&#x27;</span>, <span class="hljs-string">&#x27;!==&#x27;</span>]

  isChain: <span class="hljs-function">-&gt;</span>
    @isChainable() <span class="hljs-keyword">and</span> @first.isChainable()

  invert: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @isInOperator()
      @invertOperator = <span class="hljs-string">&#x27;!&#x27;</span>
      <span class="hljs-keyword">return</span> @
    <span class="hljs-keyword">if</span> @isChain()
      allInvertable = <span class="hljs-literal">yes</span>
      curr = this
      <span class="hljs-keyword">while</span> curr <span class="hljs-keyword">and</span> curr.operator
        allInvertable <span class="hljs-keyword">and</span>= (curr.operator <span class="hljs-keyword">of</span> INVERSIONS)
        curr = curr.first
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Parens(this).invert() <span class="hljs-keyword">unless</span> allInvertable
      curr = this
      <span class="hljs-keyword">while</span> curr <span class="hljs-keyword">and</span> curr.operator
        curr.invert = !curr.invert
        curr.operator = INVERSIONS[curr.operator]
        curr = curr.first
      this
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> op = INVERSIONS[@operator]
      @operator = op
      <span class="hljs-keyword">if</span> @first.unwrap() <span class="hljs-keyword">instanceof</span> Op
        @first.invert()
      this
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @second
      <span class="hljs-keyword">new</span> Parens(this).invert()
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @operator <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;!&#x27;</span> <span class="hljs-keyword">and</span> (fst = @first.unwrap()) <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span>
                                  fst.operator <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;!&#x27;</span>, <span class="hljs-string">&#x27;in&#x27;</span>, <span class="hljs-string">&#x27;instanceof&#x27;</span>]
      fst
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">new</span> Op <span class="hljs-string">&#x27;!&#x27;</span>, this

  unfoldSoak: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @operator <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;++&#x27;</span>, <span class="hljs-string">&#x27;--&#x27;</span>, <span class="hljs-string">&#x27;delete&#x27;</span>] <span class="hljs-keyword">and</span> unfoldSoak o, this, <span class="hljs-string">&#x27;first&#x27;</span>

  generateDo: <span class="hljs-function"><span class="hljs-params">(exp)</span> -&gt;</span>
    passedParams = []
    func = <span class="hljs-keyword">if</span> exp <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> (ref = exp.value.unwrap()) <span class="hljs-keyword">instanceof</span> Code
      ref
    <span class="hljs-keyword">else</span>
      exp
    <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> func.params <span class="hljs-keyword">or</span> []
      <span class="hljs-keyword">if</span> param.value
        passedParams.push param.value
        <span class="hljs-keyword">delete</span> param.value
      <span class="hljs-keyword">else</span>
        passedParams.push param
    call = <span class="hljs-keyword">new</span> Call exp, passedParams
    call.<span class="hljs-keyword">do</span> = <span class="hljs-literal">yes</span>
    call

  isInOperator: <span class="hljs-function">-&gt;</span>
    @originalOperator <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;in&#x27;</span>

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @isInOperator()
      inNode = <span class="hljs-keyword">new</span> In @first, @second
      <span class="hljs-keyword">return</span> (<span class="hljs-keyword">if</span> @invertOperator <span class="hljs-keyword">then</span> inNode.invert() <span class="hljs-keyword">else</span> inNode).compileNode o
    <span class="hljs-keyword">if</span> @invertOperator
      @invertOperator = <span class="hljs-literal">null</span>
      <span class="hljs-keyword">return</span> @invert().compileNode(o)
    <span class="hljs-keyword">return</span> Op::generateDo(@first).compileNode o <span class="hljs-keyword">if</span> @operator <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;do&#x27;</span>
    isChain = @isChain()</pre></div></div>
            
        </li>
        
        
        <li id="section-312">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-312">&#x00a7;</a>
              </div>
              <p>In chains, there’s no need to wrap bare obj literals in parens,
as the chained expression is wrapped.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    @first.front = @front <span class="hljs-keyword">unless</span> isChain
    @checkDeleteOperand o
    <span class="hljs-keyword">return</span> @compileContinuation o <span class="hljs-keyword">if</span> @isYield() <span class="hljs-keyword">or</span> @isAwait()
    <span class="hljs-keyword">return</span> @compileUnary        o <span class="hljs-keyword">if</span> @isUnary()
    <span class="hljs-keyword">return</span> @compileChain        o <span class="hljs-keyword">if</span> isChain
    <span class="hljs-keyword">switch</span> @operator
      <span class="hljs-keyword">when</span> <span class="hljs-string">&#x27;?&#x27;</span>  <span class="hljs-keyword">then</span> @compileExistence o, @second.isDefaultValue
      <span class="hljs-keyword">when</span> <span class="hljs-string">&#x27;//&#x27;</span> <span class="hljs-keyword">then</span> @compileFloorDivision o
      <span class="hljs-keyword">when</span> <span class="hljs-string">&#x27;%%&#x27;</span> <span class="hljs-keyword">then</span> @compileModulo o
      <span class="hljs-keyword">else</span>
        lhs = @first.compileToFragments o, LEVEL_OP
        rhs = @second.compileToFragments o, LEVEL_OP
        answer = [].concat lhs, @makeCode(<span class="hljs-string">&quot; <span class="hljs-subst">#{@operator}</span> &quot;</span>), rhs
        <span class="hljs-keyword">if</span> o.level &lt;= LEVEL_OP <span class="hljs-keyword">then</span> answer <span class="hljs-keyword">else</span> @wrapInParentheses answer</pre></div></div>
            
        </li>
        
        
        <li id="section-313">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-313">&#x00a7;</a>
              </div>
              <p>Mimic Python’s chained comparisons when multiple comparison operators are
used sequentially. For example:</p>
<pre><code>bin/coffee -e <span class="hljs-string">&#x27;console.log 50 &lt; 65 &gt; 10&#x27;</span>
<span class="hljs-literal">true</span>
</code></pre>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileChain: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [@first.second, shared] = @first.second.cache o
    fst = @first.compileToFragments o, LEVEL_OP
    fragments = fst.concat @makeCode(<span class="hljs-string">&quot; <span class="hljs-subst">#{<span class="hljs-keyword">if</span> @invert <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&amp;&amp;&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;||&#x27;</span>}</span> &quot;</span>),
      (shared.compileToFragments o), @makeCode(<span class="hljs-string">&quot; <span class="hljs-subst">#{@operator}</span> &quot;</span>), (@second.compileToFragments o, LEVEL_OP)
    @wrapInParentheses fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-314">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-314">&#x00a7;</a>
              </div>
              <p>Keep reference to the left expression, unless this an existential assignment</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileExistence: <span class="hljs-function"><span class="hljs-params">(o, checkOnlyUndefined)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @first.shouldCache()
      ref = <span class="hljs-keyword">new</span> IdentifierLiteral o.scope.freeVariable <span class="hljs-string">&#x27;ref&#x27;</span>
      fst = <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Assign ref, @first
    <span class="hljs-keyword">else</span>
      fst = @first
      ref = fst
    <span class="hljs-keyword">new</span> If(<span class="hljs-keyword">new</span> Existence(fst, checkOnlyUndefined), ref, type: <span class="hljs-string">&#x27;if&#x27;</span>).addElse(@second).compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-315">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-315">&#x00a7;</a>
              </div>
              <p>Compile a unary <strong>Op</strong>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileUnary: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    parts = []
    op = @operator
    parts.push [@makeCode op]
    <span class="hljs-keyword">if</span> op <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;!&#x27;</span> <span class="hljs-keyword">and</span> @first <span class="hljs-keyword">instanceof</span> Existence
      @first.negated = <span class="hljs-keyword">not</span> @first.negated
      <span class="hljs-keyword">return</span> @first.compileToFragments o
    <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_ACCESS
      <span class="hljs-keyword">return</span> (<span class="hljs-keyword">new</span> Parens this).compileToFragments o
    plusMinus = op <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;+&#x27;</span>, <span class="hljs-string">&#x27;-&#x27;</span>]
    parts.push [@makeCode(<span class="hljs-string">&#x27; &#x27;</span>)] <span class="hljs-keyword">if</span> op <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;typeof&#x27;</span>, <span class="hljs-string">&#x27;delete&#x27;</span>] <span class="hljs-keyword">or</span>
                      plusMinus <span class="hljs-keyword">and</span> @first <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> @first.operator <span class="hljs-keyword">is</span> op
    <span class="hljs-keyword">if</span> plusMinus <span class="hljs-keyword">and</span> @first <span class="hljs-keyword">instanceof</span> Op
      @first = <span class="hljs-keyword">new</span> Parens @first
    parts.push @first.compileToFragments o, LEVEL_OP
    parts.reverse() <span class="hljs-keyword">if</span> @flip
    @joinFragmentArrays parts, <span class="hljs-string">&#x27;&#x27;</span>

  compileContinuation: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    parts = []
    op = @operator
    @checkContinuation o <span class="hljs-keyword">unless</span> @isAwait()
    <span class="hljs-keyword">if</span> <span class="hljs-string">&#x27;expression&#x27;</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">Object</span>.keys(@first) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> (@first <span class="hljs-keyword">instanceof</span> Throw)
      parts.push @first.expression.compileToFragments o, LEVEL_OP <span class="hljs-keyword">if</span> @first.expression?
    <span class="hljs-keyword">else</span>
      parts.push [@makeCode <span class="hljs-string">&quot;(&quot;</span>] <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_PAREN
      parts.push [@makeCode op]
      parts.push [@makeCode <span class="hljs-string">&quot; &quot;</span>] <span class="hljs-keyword">if</span> @first.base?.value <span class="hljs-keyword">isnt</span> <span class="hljs-string">&#x27;&#x27;</span>
      parts.push @first.compileToFragments o, LEVEL_OP
      parts.push [@makeCode <span class="hljs-string">&quot;)&quot;</span>] <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_PAREN
    @joinFragmentArrays parts, <span class="hljs-string">&#x27;&#x27;</span>

  checkContinuation: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">unless</span> o.scope.parent?
      @error <span class="hljs-string">&quot;<span class="hljs-subst">#{@operator}</span> can only occur inside functions&quot;</span>
    <span class="hljs-keyword">if</span> o.scope.method?.bound <span class="hljs-keyword">and</span> o.scope.method.isGenerator
      @error <span class="hljs-string">&#x27;yield cannot occur inside bound (fat arrow) functions&#x27;</span>

  compileFloorDivision: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    floor = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> IdentifierLiteral(<span class="hljs-string">&#x27;Math&#x27;</span>), [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> PropertyName <span class="hljs-string">&#x27;floor&#x27;</span>]
    second = <span class="hljs-keyword">if</span> @second.shouldCache() <span class="hljs-keyword">then</span> <span class="hljs-keyword">new</span> Parens @second <span class="hljs-keyword">else</span> @second
    div = <span class="hljs-keyword">new</span> Op <span class="hljs-string">&#x27;/&#x27;</span>, @first, second
    <span class="hljs-keyword">new</span> Call(floor, [div]).compileToFragments o

  compileModulo: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    mod = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal utility <span class="hljs-string">&#x27;modulo&#x27;</span>, o
    <span class="hljs-keyword">new</span> Call(mod, [@first, @second]).compileToFragments o

  toString: <span class="hljs-function"><span class="hljs-params">(idt)</span> -&gt;</span>
    super idt, @constructor.name + <span class="hljs-string">&#x27; &#x27;</span> + @operator

  checkDeleteOperand: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @operator <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;delete&#x27;</span> <span class="hljs-keyword">and</span> o.scope.check(@first.unwrapAll().value)
      @error <span class="hljs-string">&#x27;delete operand may not be argument or var&#x27;</span>

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkContinuation o <span class="hljs-keyword">if</span> @isYield()
    @checkDeleteOperand o
    super o

  astType: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;AwaitExpression&#x27;</span> <span class="hljs-keyword">if</span> @isAwait()
    <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;YieldExpression&#x27;</span> <span class="hljs-keyword">if</span> @isYield()
    <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;ChainedComparison&#x27;</span> <span class="hljs-keyword">if</span> @isChain()
    <span class="hljs-keyword">switch</span> @operator
      <span class="hljs-keyword">when</span> <span class="hljs-string">&#x27;||&#x27;</span>, <span class="hljs-string">&#x27;&amp;&amp;&#x27;</span>, <span class="hljs-string">&#x27;?&#x27;</span> <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;LogicalExpression&#x27;</span>
      <span class="hljs-keyword">when</span> <span class="hljs-string">&#x27;++&#x27;</span>, <span class="hljs-string">&#x27;--&#x27;</span>      <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;UpdateExpression&#x27;</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> @isUnary()      <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;UnaryExpression&#x27;</span>
        <span class="hljs-keyword">else</span>                    <span class="hljs-string">&#x27;BinaryExpression&#x27;</span>

  operatorAst: <span class="hljs-function">-&gt;</span>
    <span class="hljs-string">&quot;<span class="hljs-subst">#{<span class="hljs-keyword">if</span> @invertOperator <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{@invertOperator}</span> &quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>}</span><span class="hljs-subst">#{@originalOperator}</span>&quot;</span>

  chainAstProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    operators = [@operatorAst()]
    operands = [@second]
    currentOp = @first
    <span class="hljs-keyword">loop</span>
      operators.unshift currentOp.operatorAst()
      operands.unshift currentOp.second
      currentOp = currentOp.first
      <span class="hljs-keyword">unless</span> currentOp.isChainable()
        operands.unshift currentOp
        <span class="hljs-keyword">break</span>
    <span class="hljs-keyword">return</span> {
      operators
      operands: (operand.ast(o, LEVEL_OP) <span class="hljs-keyword">for</span> operand <span class="hljs-keyword">in</span> operands)
    }

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> @chainAstProperties(o) <span class="hljs-keyword">if</span> @isChain()

    firstAst = @first.ast o, LEVEL_OP
    secondAst = @second?.ast o, LEVEL_OP
    operatorAst = @operatorAst()
    <span class="hljs-keyword">switch</span>
      <span class="hljs-keyword">when</span> @isUnary()
        argument =
          <span class="hljs-keyword">if</span> @isYield() <span class="hljs-keyword">and</span> @first.unwrap().value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;&#x27;</span>
            <span class="hljs-literal">null</span>
          <span class="hljs-keyword">else</span>
            firstAst
        <span class="hljs-keyword">return</span> {argument} <span class="hljs-keyword">if</span> @isAwait()
        <span class="hljs-keyword">return</span> {
          argument
          delegate: @operator <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;yield*&#x27;</span>
        } <span class="hljs-keyword">if</span> @isYield()
        <span class="hljs-keyword">return</span> {
          argument
          operator: operatorAst
          prefix: !@flip
        }
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">return</span>
          left: firstAst
          right: secondAst
          operator: operatorAst</pre></div></div>
            
        </li>
        
        
        <li id="section-316">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-316">&#x00a7;</a>
              </div>
              <h3 id="in">In</h3>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.In = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">In</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@object, @array)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;object&#x27;</span>, <span class="hljs-string">&#x27;array&#x27;</span>]

  invert: NEGATE

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @array <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> @array.isArray() <span class="hljs-keyword">and</span> @array.base.objects.length
      <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> @array.base.objects <span class="hljs-keyword">when</span> obj <span class="hljs-keyword">instanceof</span> Splat
        hasSplat = <span class="hljs-literal">yes</span>
        <span class="hljs-keyword">break</span></pre></div></div>
            
        </li>
        
        
        <li id="section-317">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-317">&#x00a7;</a>
              </div>
              <p><code>compileOrTest</code> only if we have an array literal with no splats</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">return</span> @compileOrTest o <span class="hljs-keyword">unless</span> hasSplat
    @compileLoopTest o

  compileOrTest: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [sub, ref] = @object.cache o, LEVEL_OP
    [cmp, cnj] = <span class="hljs-keyword">if</span> @negated <span class="hljs-keyword">then</span> [<span class="hljs-string">&#x27; !== &#x27;</span>, <span class="hljs-string">&#x27; &amp;&amp; &#x27;</span>] <span class="hljs-keyword">else</span> [<span class="hljs-string">&#x27; === &#x27;</span>, <span class="hljs-string">&#x27; || &#x27;</span>]
    tests = []
    <span class="hljs-keyword">for</span> item, i <span class="hljs-keyword">in</span> @array.base.objects
      <span class="hljs-keyword">if</span> i <span class="hljs-keyword">then</span> tests.push @makeCode cnj
      tests = tests.concat (<span class="hljs-keyword">if</span> i <span class="hljs-keyword">then</span> ref <span class="hljs-keyword">else</span> sub), @makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS)
    <span class="hljs-keyword">if</span> o.level &lt; LEVEL_OP <span class="hljs-keyword">then</span> tests <span class="hljs-keyword">else</span> @wrapInParentheses tests

  compileLoopTest: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [sub, ref] = @object.cache o, LEVEL_LIST
    fragments = [].concat @makeCode(utility(<span class="hljs-string">&#x27;indexOf&#x27;</span>, o) + <span class="hljs-string">&quot;.call(&quot;</span>), @array.compileToFragments(o, LEVEL_LIST),
      @makeCode(<span class="hljs-string">&quot;, &quot;</span>), ref, @makeCode(<span class="hljs-string">&quot;) &quot;</span> + <span class="hljs-keyword">if</span> @negated <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&lt; 0&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&gt;= 0&#x27;</span>)
    <span class="hljs-keyword">return</span> fragments <span class="hljs-keyword">if</span> fragmentsToText(sub) <span class="hljs-keyword">is</span> fragmentsToText(ref)
    fragments = sub.concat @makeCode(<span class="hljs-string">&#x27;, &#x27;</span>), fragments
    <span class="hljs-keyword">if</span> o.level &lt; LEVEL_LIST <span class="hljs-keyword">then</span> fragments <span class="hljs-keyword">else</span> @wrapInParentheses fragments

  toString: <span class="hljs-function"><span class="hljs-params">(idt)</span> -&gt;</span>
    super idt, @constructor.name + <span class="hljs-keyword">if</span> @negated <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;!&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-318">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-318">&#x00a7;</a>
              </div>
              <h3 id="try">Try</h3>

            </div>
            
        </li>
        
        
        <li id="section-319">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-319">&#x00a7;</a>
              </div>
              <p>A classic <em>try/catch/finally</em> block.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Try = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Try</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@attempt, @catch, @ensure, @finallyTag)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;attempt&#x27;</span>, <span class="hljs-string">&#x27;catch&#x27;</span>, <span class="hljs-string">&#x27;ensure&#x27;</span>]

  isStatement: YES

  jumps: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> @attempt.jumps(o) <span class="hljs-keyword">or</span> @catch?.jumps(o)

  makeReturn: <span class="hljs-function"><span class="hljs-params">(results, mark)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> mark
      @attempt?.makeReturn results, mark
      @catch?.makeReturn results, mark
      <span class="hljs-keyword">return</span>
    @attempt = @attempt.makeReturn results <span class="hljs-keyword">if</span> @attempt
    @catch   = @catch  .makeReturn results <span class="hljs-keyword">if</span> @catch
    this</pre></div></div>
            
        </li>
        
        
        <li id="section-320">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-320">&#x00a7;</a>
              </div>
              <p>Compilation is more or less as you would expect – the <em>finally</em> clause
is optional, the <em>catch</em> is not.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    originalIndent = o.indent
    o.indent  += TAB
    tryPart   = @attempt.compileToFragments o, LEVEL_TOP

    catchPart = <span class="hljs-keyword">if</span> @catch
      @catch.compileToFragments merge(o, indent: originalIndent), LEVEL_TOP
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">unless</span> @ensure <span class="hljs-keyword">or</span> @catch
      generatedErrorVariableName = o.scope.freeVariable <span class="hljs-string">&#x27;error&#x27;</span>, reserve: <span class="hljs-literal">no</span>
      [@makeCode(<span class="hljs-string">&quot; catch (<span class="hljs-subst">#{generatedErrorVariableName}</span>) {}&quot;</span>)]
    <span class="hljs-keyword">else</span>
      []

    ensurePart = <span class="hljs-keyword">if</span> @ensure <span class="hljs-keyword">then</span> ([].concat @makeCode(<span class="hljs-string">&quot; finally {\n&quot;</span>), @ensure.compileToFragments(o, LEVEL_TOP),
      @makeCode(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>}&quot;</span>)) <span class="hljs-keyword">else</span> []

    [].concat @makeCode(<span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span>try {\n&quot;</span>),
      tryPart,
      @makeCode(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>}&quot;</span>), catchPart, ensurePart

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;TryStatement&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      block: @attempt.ast o, LEVEL_TOP
      handler: @catch?.ast(o) ? <span class="hljs-literal">null</span>
      finalizer:
        <span class="hljs-keyword">if</span> @ensure?
          <span class="hljs-built_in">Object</span>.assign @ensure.ast(o, LEVEL_TOP),</pre></div></div>
            
        </li>
        
        
        <li id="section-321">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-321">&#x00a7;</a>
              </div>
              <p>Include <code>finally</code> keyword in location data.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            mergeAstLocationData(
              jisonLocationDataToAstLocationData(@finallyTag.locationData),
              @ensure.astLocationData()
            )
        <span class="hljs-keyword">else</span>
          <span class="hljs-literal">null</span>

<span class="hljs-built_in">exports</span>.Catch = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Catch</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@recovery, @errorVariable)</span> -&gt;</span>
    super()
    @errorVariable?.unwrap().propagateLhs? <span class="hljs-literal">yes</span>

  children: [<span class="hljs-string">&#x27;recovery&#x27;</span>, <span class="hljs-string">&#x27;errorVariable&#x27;</span>]

  isStatement: YES

  jumps: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> @recovery.jumps o

  makeReturn: <span class="hljs-function"><span class="hljs-params">(results, mark)</span> -&gt;</span>
    ret = @recovery.makeReturn results, mark
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> mark
    @recovery = ret
    this

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.indent  += TAB
    generatedErrorVariableName = o.scope.freeVariable <span class="hljs-string">&#x27;error&#x27;</span>, reserve: <span class="hljs-literal">no</span>
    placeholder = <span class="hljs-keyword">new</span> IdentifierLiteral generatedErrorVariableName
    @checkUnassignable()
    <span class="hljs-keyword">if</span> @errorVariable
      @recovery.unshift <span class="hljs-keyword">new</span> Assign @errorVariable, placeholder
    [].concat @makeCode(<span class="hljs-string">&quot; catch (&quot;</span>), placeholder.compileToFragments(o), @makeCode(<span class="hljs-string">&quot;) {\n&quot;</span>),
      @recovery.compileToFragments(o, LEVEL_TOP), @makeCode(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>}&quot;</span>)

  checkUnassignable: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">if</span> @errorVariable
      message = isUnassignable @errorVariable.unwrapAll().value
      @errorVariable.error message <span class="hljs-keyword">if</span> message

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @checkUnassignable()
    @errorVariable?.eachName (name) -&gt;
      alreadyDeclared = o.scope.find name.value
      name.isDeclaration = <span class="hljs-keyword">not</span> alreadyDeclared

    super o

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;CatchClause&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      param: @errorVariable?.ast(o) ? <span class="hljs-literal">null</span>
      body: @recovery.ast o, LEVEL_TOP</pre></div></div>
            
        </li>
        
        
        <li id="section-322">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-322">&#x00a7;</a>
              </div>
              <h3 id="throw">Throw</h3>

            </div>
            
        </li>
        
        
        <li id="section-323">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-323">&#x00a7;</a>
              </div>
              <p>Simple node to throw an exception.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Throw = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Throw</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@expression)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;expression&#x27;</span>]

  isStatement: YES
  jumps:       NO</pre></div></div>
            
        </li>
        
        
        <li id="section-324">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-324">&#x00a7;</a>
              </div>
              <p>A <strong>Throw</strong> is already a return, of sorts…</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  makeReturn: THIS

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    fragments = @expression.compileToFragments o, LEVEL_LIST
    unshiftAfterComments fragments, @makeCode <span class="hljs-string">&#x27;throw &#x27;</span>
    fragments.unshift @makeCode @tab
    fragments.push @makeCode <span class="hljs-string">&#x27;;&#x27;</span>
    fragments

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;ThrowStatement&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      argument: @expression.ast o, LEVEL_LIST</pre></div></div>
            
        </li>
        
        
        <li id="section-325">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-325">&#x00a7;</a>
              </div>
              <h3 id="existence">Existence</h3>

            </div>
            
        </li>
        
        
        <li id="section-326">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-326">&#x00a7;</a>
              </div>
              <p>Checks a variable for existence – not <code>null</code> and not <code>undefined</code>. This is
similar to <code>.nil?</code> in Ruby, and avoids having to consult a JavaScript truth
table. Optionally only check if a variable is not <code>undefined</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Existence = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Existence</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@expression, onlyNotUndefined = <span class="hljs-literal">no</span>)</span> -&gt;</span>
    super()
    @comparisonTarget = <span class="hljs-keyword">if</span> onlyNotUndefined <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;undefined&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;null&#x27;</span>
    salvagedComments = []
    @expression.traverseChildren <span class="hljs-literal">yes</span>, <span class="hljs-function"><span class="hljs-params">(child)</span> -&gt;</span>
      <span class="hljs-keyword">if</span> child.comments
        <span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> child.comments
          salvagedComments.push comment <span class="hljs-keyword">unless</span> comment <span class="hljs-keyword">in</span> salvagedComments
        <span class="hljs-keyword">delete</span> child.comments
    attachCommentsToNode salvagedComments, @
    moveComments @expression, @

  children: [<span class="hljs-string">&#x27;expression&#x27;</span>]

  invert: NEGATE

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @expression.front = @front
    code = @expression.compile o, LEVEL_OP
    <span class="hljs-keyword">if</span> @expression.unwrap() <span class="hljs-keyword">instanceof</span> IdentifierLiteral <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> o.scope.check code
      [cmp, cnj] = <span class="hljs-keyword">if</span> @negated <span class="hljs-keyword">then</span> [<span class="hljs-string">&#x27;===&#x27;</span>, <span class="hljs-string">&#x27;||&#x27;</span>] <span class="hljs-keyword">else</span> [<span class="hljs-string">&#x27;!==&#x27;</span>, <span class="hljs-string">&#x27;&amp;&amp;&#x27;</span>]
      code = <span class="hljs-string">&quot;typeof <span class="hljs-subst">#{code}</span> <span class="hljs-subst">#{cmp}</span> \&quot;undefined\&quot;&quot;</span> + <span class="hljs-keyword">if</span> @comparisonTarget <span class="hljs-keyword">isnt</span> <span class="hljs-string">&#x27;undefined&#x27;</span> <span class="hljs-keyword">then</span> <span class="hljs-string">&quot; <span class="hljs-subst">#{cnj}</span> <span class="hljs-subst">#{code}</span> <span class="hljs-subst">#{cmp}</span> <span class="hljs-subst">#{@comparisonTarget}</span>&quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>
    <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-327">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-327">&#x00a7;</a>
              </div>
              <p>We explicity want to use loose equality (<code>==</code>) when comparing against <code>null</code>,
so that an existence check roughly corresponds to a check for truthiness.
Do <em>not</em> change this to <code>===</code> for <code>null</code>, as this will break mountains of
existing code. When comparing only against <code>undefined</code>, however, we want to
use <code>===</code> because this use case is for parity with ES2015+ default values,
which only get assigned when the variable is <code>undefined</code> (but not <code>null</code>).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      cmp = <span class="hljs-keyword">if</span> @comparisonTarget <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;null&#x27;</span>
        <span class="hljs-keyword">if</span> @negated <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;==&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;!=&#x27;</span>
      <span class="hljs-keyword">else</span> <span class="hljs-comment"># `undefined`</span>
        <span class="hljs-keyword">if</span> @negated <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;===&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;!==&#x27;</span>
      code = <span class="hljs-string">&quot;<span class="hljs-subst">#{code}</span> <span class="hljs-subst">#{cmp}</span> <span class="hljs-subst">#{@comparisonTarget}</span>&quot;</span>
    [@makeCode(<span class="hljs-keyword">if</span> o.level &lt;= LEVEL_COND <span class="hljs-keyword">then</span> code <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;(<span class="hljs-subst">#{code}</span>)&quot;</span>)]

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;UnaryExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      argument: @expression.ast o
      operator: <span class="hljs-string">&#x27;?&#x27;</span>
      prefix: <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-328">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-328">&#x00a7;</a>
              </div>
              <h3 id="parens">Parens</h3>

            </div>
            
        </li>
        
        
        <li id="section-329">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-329">&#x00a7;</a>
              </div>
              <p>An extra set of parentheses, specified explicitly in the source. At one time
we tried to clean up the results by detecting and removing redundant
parentheses, but no longer – you can put in as many as you please.</p>
<p>Parentheses are a good way to force any statement to become an expression.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Parens = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Parens</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@body)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;body&#x27;</span>]

  unwrap: <span class="hljs-function">-&gt;</span> @body

  shouldCache: <span class="hljs-function">-&gt;</span> @body.shouldCache()

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    expr = @body.unwrap()</pre></div></div>
            
        </li>
        
        
        <li id="section-330">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-330">&#x00a7;</a>
              </div>
              <p>If these parentheses are wrapping an <code>IdentifierLiteral</code> followed by a
block comment, output the parentheses (or put another way, don’t optimize
away these redundant parentheses). This is because Flow requires
parentheses in certain circumstances to distinguish identifiers followed
by comment-based type annotations from JavaScript labels.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    shouldWrapComment = expr.comments?.some(
      <span class="hljs-function"><span class="hljs-params">(comment)</span> -&gt;</span> comment.here <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> comment.unshift <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> comment.newLine)
    <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> expr.isAtomic() <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @jsxAttribute <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> shouldWrapComment
      expr.front = @front
      <span class="hljs-keyword">return</span> expr.compileToFragments o
    fragments = expr.compileToFragments o, LEVEL_PAREN
    bare = o.level &lt; LEVEL_OP <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> shouldWrapComment <span class="hljs-keyword">and</span> (
        expr <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> expr.isInOperator() <span class="hljs-keyword">or</span> expr.unwrap() <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">or</span>
        (expr <span class="hljs-keyword">instanceof</span> For <span class="hljs-keyword">and</span> expr.returns)
      ) <span class="hljs-keyword">and</span> (o.level &lt; LEVEL_COND <span class="hljs-keyword">or</span> fragments.length &lt;= <span class="hljs-number">3</span>)
    <span class="hljs-keyword">return</span> @wrapInBraces fragments <span class="hljs-keyword">if</span> @jsxAttribute
    <span class="hljs-keyword">if</span> bare <span class="hljs-keyword">then</span> fragments <span class="hljs-keyword">else</span> @wrapInParentheses fragments

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> @body.unwrap().ast o, LEVEL_PAREN</pre></div></div>
            
        </li>
        
        
        <li id="section-331">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-331">&#x00a7;</a>
              </div>
              <h3 id="stringwithinterpolations">StringWithInterpolations</h3>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-built_in">exports</span>.StringWithInterpolations = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StringWithInterpolations</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@body, {@quote, @startQuote, @jsxAttribute} = {})</span> -&gt;</span>
    super()

  @fromStringLiteral: <span class="hljs-function"><span class="hljs-params">(stringLiteral)</span> -&gt;</span>
    updatedString = stringLiteral.withoutQuotesInLocationData()
    updatedStringValue = <span class="hljs-keyword">new</span> Value(updatedString).withLocationDataFrom updatedString
    <span class="hljs-keyword">new</span> StringWithInterpolations Block.wrap([updatedStringValue]), quote: stringLiteral.quote, jsxAttribute: stringLiteral.jsxAttribute
    .withLocationDataFrom stringLiteral

  children: [<span class="hljs-string">&#x27;body&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-332">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-332">&#x00a7;</a>
              </div>
              <p><code>unwrap</code> returns <code>this</code> to stop ancestor nodes reaching in to grab @body,
and using @body.compileNode. <code>StringWithInterpolations.compileNode</code> is
<em>the</em> custom logic to output interpolated strings as code.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  unwrap: <span class="hljs-function">-&gt;</span> this

  shouldCache: <span class="hljs-function">-&gt;</span> @body.shouldCache()

  extractElements: <span class="hljs-function"><span class="hljs-params">(o, {includeInterpolationWrappers, isJsx} = {})</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-333">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-333">&#x00a7;</a>
              </div>
              <p>Assumes that <code>expr</code> is <code>Block</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    expr = @body.unwrap()

    elements = []
    salvagedComments = []
    expr.traverseChildren <span class="hljs-literal">no</span>, <span class="hljs-function"><span class="hljs-params">(node)</span> =&gt;</span>
      <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> StringLiteral
        <span class="hljs-keyword">if</span> node.comments
          salvagedComments.push node.comments...
          <span class="hljs-keyword">delete</span> node.comments
        elements.push node
        <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Interpolation
        <span class="hljs-keyword">if</span> salvagedComments.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
          <span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> salvagedComments
            comment.unshift = <span class="hljs-literal">yes</span>
            comment.newLine = <span class="hljs-literal">yes</span>
          attachCommentsToNode salvagedComments, node
        <span class="hljs-keyword">if</span> (unwrapped = node.expression?.unwrapAll()) <span class="hljs-keyword">instanceof</span> PassthroughLiteral <span class="hljs-keyword">and</span> unwrapped.generated <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> (isJsx <span class="hljs-keyword">and</span> o.compiling)
          <span class="hljs-keyword">if</span> o.compiling
            commentPlaceholder = <span class="hljs-keyword">new</span> StringLiteral(<span class="hljs-string">&#x27;&#x27;</span>).withLocationDataFrom node
            commentPlaceholder.comments = unwrapped.comments
            (commentPlaceholder.comments ?= []).push node.comments... <span class="hljs-keyword">if</span> node.comments
            elements.push <span class="hljs-keyword">new</span> Value commentPlaceholder
          <span class="hljs-keyword">else</span>
            empty = <span class="hljs-keyword">new</span> Interpolation().withLocationDataFrom node
            empty.comments = node.comments
            elements.push empty
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node.expression <span class="hljs-keyword">or</span> includeInterpolationWrappers
          (node.expression?.comments ?= []).push node.comments... <span class="hljs-keyword">if</span> node.comments
          elements.push <span class="hljs-keyword">if</span> includeInterpolationWrappers <span class="hljs-keyword">then</span> node <span class="hljs-keyword">else</span> node.expression
        <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node.comments</pre></div></div>
            
        </li>
        
        
        <li id="section-334">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-334">&#x00a7;</a>
              </div>
              <p>This node is getting discarded, but salvage its comments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">if</span> elements.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> elements[elements.length - <span class="hljs-number">1</span>] <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> StringLiteral
          <span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> node.comments
            comment.unshift = <span class="hljs-literal">no</span>
            comment.newLine = <span class="hljs-literal">yes</span>
          attachCommentsToNode node.comments, elements[elements.length - <span class="hljs-number">1</span>]
        <span class="hljs-keyword">else</span>
          salvagedComments.push node.comments...
        <span class="hljs-keyword">delete</span> node.comments
      <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>

    elements

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    @comments ?= @startQuote?.comments

    <span class="hljs-keyword">if</span> @jsxAttribute
      wrapped = <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> StringWithInterpolations @body
      wrapped.jsxAttribute = <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">return</span> wrapped.compileNode o

    elements = @extractElements o, isJsx: @jsx

    fragments = []
    fragments.push @makeCode <span class="hljs-string">&#x27;`&#x27;</span> <span class="hljs-keyword">unless</span> @jsx
    <span class="hljs-keyword">for</span> element <span class="hljs-keyword">in</span> elements
      <span class="hljs-keyword">if</span> element <span class="hljs-keyword">instanceof</span> StringLiteral
        unquotedElementValue = <span class="hljs-keyword">if</span> @jsx <span class="hljs-keyword">then</span> element.unquotedValueForJSX <span class="hljs-keyword">else</span> element.unquotedValueForTemplateLiteral
        fragments.push @makeCode unquotedElementValue
      <span class="hljs-keyword">else</span>
        fragments.push @makeCode <span class="hljs-string">&#x27;$&#x27;</span> <span class="hljs-keyword">unless</span> @jsx
        code = element.compileToFragments(o, LEVEL_PAREN)
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> @isNestedTag(element) <span class="hljs-keyword">or</span>
           code.some(<span class="hljs-function"><span class="hljs-params">(fragment)</span> -&gt;</span> fragment.comments?.some(<span class="hljs-function"><span class="hljs-params">(comment)</span> -&gt;</span> comment.here <span class="hljs-keyword">is</span> <span class="hljs-literal">no</span>))
          code = @wrapInBraces code</pre></div></div>
            
        </li>
        
        
        <li id="section-335">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-335">&#x00a7;</a>
              </div>
              <p>Flag the <code>{</code> and <code>}</code> fragments as having been generated by this
<code>StringWithInterpolations</code> node, so that <code>compileComments</code> knows
to treat them as bounds. But the braces are unnecessary if all of
the enclosed comments are <code>/* */</code> comments. Don’t trust
<code>fragment.type</code>, which can report minified variable names when
this compiler is minified.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          code[<span class="hljs-number">0</span>].isStringWithInterpolations = <span class="hljs-literal">yes</span>
          code[code.length - <span class="hljs-number">1</span>].isStringWithInterpolations = <span class="hljs-literal">yes</span>
        fragments.push code...
    fragments.push @makeCode <span class="hljs-string">&#x27;`&#x27;</span> <span class="hljs-keyword">unless</span> @jsx
    fragments

  isNestedTag: <span class="hljs-function"><span class="hljs-params">(element)</span> -&gt;</span>
    call = element.unwrapAll?()
    @jsx <span class="hljs-keyword">and</span> call <span class="hljs-keyword">instanceof</span> JSXElement

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;TemplateLiteral&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    elements = @extractElements o, includeInterpolationWrappers: <span class="hljs-literal">yes</span>
    [..., last] = elements

    quasis = []
    expressions = []

    <span class="hljs-keyword">for</span> element, index <span class="hljs-keyword">in</span> elements
      <span class="hljs-keyword">if</span> element <span class="hljs-keyword">instanceof</span> StringLiteral
        quasis.push <span class="hljs-keyword">new</span> TemplateElement(
          element.originalValue
          tail: element <span class="hljs-keyword">is</span> last
        ).withLocationDataFrom(element).ast o
      <span class="hljs-keyword">else</span> <span class="hljs-comment"># Interpolation</span>
        {expression} = element
        node =
          <span class="hljs-keyword">unless</span> expression?
            emptyInterpolation = <span class="hljs-keyword">new</span> EmptyInterpolation()
            emptyInterpolation.locationData = emptyExpressionLocationData {
              interpolationNode: element
              openingBrace: <span class="hljs-string">&#x27;#{&#x27;</span>
              closingBrace: <span class="hljs-string">&#x27;}&#x27;</span>
            }
            emptyInterpolation
          <span class="hljs-keyword">else</span>
            expression.unwrapAll()
        expressions.push astAsBlockIfNeeded node, o

    {expressions, quasis, @quote}

<span class="hljs-built_in">exports</span>.TemplateElement = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TemplateElement</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@value, {@tail} = {})</span> -&gt;</span>
    super()

  astProperties: <span class="hljs-function">-&gt;</span>
    <span class="hljs-keyword">return</span>
      value:
        raw: @value
      tail: !!@tail

<span class="hljs-built_in">exports</span>.Interpolation = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Interpolation</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@expression)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;expression&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-336">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-336">&#x00a7;</a>
              </div>
              <p>Represents the contents of an empty interpolation (e.g. <code>#{}</code>).
Only used during AST generation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.EmptyInterpolation = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EmptyInterpolation</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function">-&gt;</span>
    super()</pre></div></div>
            
        </li>
        
        
        <li id="section-337">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-337">&#x00a7;</a>
              </div>
              <h3 id="for">For</h3>

            </div>
            
        </li>
        
        
        <li id="section-338">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-338">&#x00a7;</a>
              </div>
              <p>CoffeeScript’s replacement for the <em>for</em> loop is our array and object
comprehensions, that compile into <em>for</em> loops here. They also act as an
expression, able to return the result of each filtered iteration.</p>
<p>Unlike Python array comprehensions, they can be multi-line, and you can pass
the current index of the loop as a second parameter. Unlike Ruby blocks,
you can map and filter in a single pass.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.For = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">For</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">While</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(body, source)</span> -&gt;</span>
    super()
    @addBody body
    @addSource source

  children: [<span class="hljs-string">&#x27;body&#x27;</span>, <span class="hljs-string">&#x27;source&#x27;</span>, <span class="hljs-string">&#x27;guard&#x27;</span>, <span class="hljs-string">&#x27;step&#x27;</span>]

  isAwait: <span class="hljs-function">-&gt;</span> @await ? <span class="hljs-literal">no</span>

  addBody: <span class="hljs-function"><span class="hljs-params">(body)</span> -&gt;</span>
    @body = Block.wrap [body]
    {expressions} = @body
    <span class="hljs-keyword">if</span> expressions.length
      @body.locationData ?= mergeLocationData expressions[<span class="hljs-number">0</span>].locationData, expressions[expressions.length - <span class="hljs-number">1</span>].locationData
    this

  addSource: <span class="hljs-function"><span class="hljs-params">(source)</span> -&gt;</span>
    {@source  = <span class="hljs-literal">no</span>} = source
    attribs   = [<span class="hljs-string">&quot;name&quot;</span>, <span class="hljs-string">&quot;index&quot;</span>, <span class="hljs-string">&quot;guard&quot;</span>, <span class="hljs-string">&quot;step&quot;</span>, <span class="hljs-string">&quot;own&quot;</span>, <span class="hljs-string">&quot;ownTag&quot;</span>, <span class="hljs-string">&quot;await&quot;</span>, <span class="hljs-string">&quot;awaitTag&quot;</span>, <span class="hljs-string">&quot;object&quot;</span>, <span class="hljs-string">&quot;from&quot;</span>]
    @[attr]   = source[attr] ? @[attr] <span class="hljs-keyword">for</span> attr <span class="hljs-keyword">in</span> attribs
    <span class="hljs-keyword">return</span> this <span class="hljs-keyword">unless</span> @source
    @index.error <span class="hljs-string">&#x27;cannot use index with for-from&#x27;</span> <span class="hljs-keyword">if</span> @from <span class="hljs-keyword">and</span> @index
    @ownTag.error <span class="hljs-string">&quot;cannot use own with for-<span class="hljs-subst">#{<span class="hljs-keyword">if</span> @from <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;from&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;in&#x27;</span>}</span>&quot;</span> <span class="hljs-keyword">if</span> @own <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @object
    [@name, @index] = [@index, @name] <span class="hljs-keyword">if</span> @object
    @index.error <span class="hljs-string">&#x27;index cannot be a pattern matching expression&#x27;</span> <span class="hljs-keyword">if</span> @index?.isArray?() <span class="hljs-keyword">or</span> @index?.isObject?()
    @awaitTag.error <span class="hljs-string">&#x27;await must be used with for-from&#x27;</span> <span class="hljs-keyword">if</span> @await <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @from
    @range   = @source <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> @source.base <span class="hljs-keyword">instanceof</span> Range <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @source.properties.length <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @from
    @pattern = @name <span class="hljs-keyword">instanceof</span> Value
    @name.unwrap().propagateLhs?(<span class="hljs-literal">yes</span>) <span class="hljs-keyword">if</span> @pattern
    @index.error <span class="hljs-string">&#x27;indexes do not apply to range loops&#x27;</span> <span class="hljs-keyword">if</span> @range <span class="hljs-keyword">and</span> @index
    @name.error <span class="hljs-string">&#x27;cannot pattern match over range loops&#x27;</span> <span class="hljs-keyword">if</span> @range <span class="hljs-keyword">and</span> @pattern
    @returns = <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-339">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-339">&#x00a7;</a>
              </div>
              <p>Move up any comments in the “<code>for</code> line”, i.e. the line of code with <code>for</code>,
from any child nodes of that line up to the <code>for</code> node itself so that these
comments get output, and get output above the <code>for</code> loop.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">for</span> attribute <span class="hljs-keyword">in</span> [<span class="hljs-string">&#x27;source&#x27;</span>, <span class="hljs-string">&#x27;guard&#x27;</span>, <span class="hljs-string">&#x27;step&#x27;</span>, <span class="hljs-string">&#x27;name&#x27;</span>, <span class="hljs-string">&#x27;index&#x27;</span>] <span class="hljs-keyword">when</span> @[attribute]
      @[attribute].traverseChildren <span class="hljs-literal">yes</span>, <span class="hljs-function"><span class="hljs-params">(node)</span> =&gt;</span>
        <span class="hljs-keyword">if</span> node.comments</pre></div></div>
            
        </li>
        
        
        <li id="section-340">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-340">&#x00a7;</a>
              </div>
              <p>These comments are buried pretty deeply, so if they happen to be
trailing comments the line they trail will be unrecognizable when
we’re done compiling this <code>for</code> loop; so just shift them up to
output above the <code>for</code> line.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          comment.newLine = comment.unshift = <span class="hljs-literal">yes</span> <span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> node.comments
          moveComments node, @[attribute]
      moveComments @[attribute], @
    this</pre></div></div>
            
        </li>
        
        
        <li id="section-341">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-341">&#x00a7;</a>
              </div>
              <p>Welcome to the hairiest method in all of CoffeeScript. Handles the inner
loop, filtering, stepping, and result saving for array, object, and range
comprehensions. Some of the generated code can be shared in common, and
some cannot.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    body        = Block.wrap [@body]
    [..., last] = body.expressions
    @returns    = <span class="hljs-literal">no</span> <span class="hljs-keyword">if</span> last?.jumps() <span class="hljs-keyword">instanceof</span> Return
    source      = <span class="hljs-keyword">if</span> @range <span class="hljs-keyword">then</span> @source.base <span class="hljs-keyword">else</span> @source
    scope       = o.scope
    name        = @name  <span class="hljs-keyword">and</span> (@name.compile o, LEVEL_LIST) <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> @pattern
    index       = @index <span class="hljs-keyword">and</span> (@index.compile o, LEVEL_LIST)
    scope.find(name)  <span class="hljs-keyword">if</span> name <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @pattern
    scope.find(index) <span class="hljs-keyword">if</span> index <span class="hljs-keyword">and</span> @index <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Value
    rvar        = scope.freeVariable <span class="hljs-string">&#x27;results&#x27;</span> <span class="hljs-keyword">if</span> @returns
    <span class="hljs-keyword">if</span> @from
      ivar = scope.freeVariable <span class="hljs-string">&#x27;x&#x27;</span>, single: <span class="hljs-literal">true</span> <span class="hljs-keyword">if</span> @pattern
    <span class="hljs-keyword">else</span>
      ivar = (@object <span class="hljs-keyword">and</span> index) <span class="hljs-keyword">or</span> scope.freeVariable <span class="hljs-string">&#x27;i&#x27;</span>, single: <span class="hljs-literal">true</span>
    kvar        = ((@range <span class="hljs-keyword">or</span> @from) <span class="hljs-keyword">and</span> name) <span class="hljs-keyword">or</span> index <span class="hljs-keyword">or</span> ivar
    kvarAssign  = <span class="hljs-keyword">if</span> kvar <span class="hljs-keyword">isnt</span> ivar <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{kvar}</span> = &quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;&quot;</span>
    <span class="hljs-keyword">if</span> @step <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @range
      [step, stepVar] = @cacheToCodeFragments @step.cache o, LEVEL_LIST, shouldCacheOrIsAssignable
      stepNum   = parseNumber stepVar <span class="hljs-keyword">if</span> @step.isNumber()
    name        = ivar <span class="hljs-keyword">if</span> @pattern
    varPart     = <span class="hljs-string">&#x27;&#x27;</span>
    guardPart   = <span class="hljs-string">&#x27;&#x27;</span>
    defPart     = <span class="hljs-string">&#x27;&#x27;</span>
    idt1        = @tab + TAB
    <span class="hljs-keyword">if</span> @range
      forPartFragments = source.compileToFragments merge o,
        {index: ivar, name, @step, shouldCache: shouldCacheOrIsAssignable}
    <span class="hljs-keyword">else</span>
      svar    = @source.compile o, LEVEL_LIST
      <span class="hljs-keyword">if</span> (name <span class="hljs-keyword">or</span> @own) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @from <span class="hljs-keyword">and</span> @source.unwrap() <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> IdentifierLiteral
        defPart    += <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span><span class="hljs-subst">#{ref = scope.freeVariable <span class="hljs-string">&#x27;ref&#x27;</span>}</span> = <span class="hljs-subst">#{svar}</span>;\n&quot;</span>
        svar       = ref
      <span class="hljs-keyword">if</span> name <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @pattern <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @from
        namePart   = <span class="hljs-string">&quot;<span class="hljs-subst">#{name}</span> = <span class="hljs-subst">#{svar}</span>[<span class="hljs-subst">#{kvar}</span>]&quot;</span>
      <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> @object <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @from
        defPart += <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span><span class="hljs-subst">#{step}</span>;\n&quot;</span> <span class="hljs-keyword">if</span> step <span class="hljs-keyword">isnt</span> stepVar
        down = stepNum &lt; <span class="hljs-number">0</span>
        lvar = scope.freeVariable <span class="hljs-string">&#x27;len&#x27;</span> <span class="hljs-keyword">unless</span> @step <span class="hljs-keyword">and</span> stepNum? <span class="hljs-keyword">and</span> down
        declare = <span class="hljs-string">&quot;<span class="hljs-subst">#{kvarAssign}</span><span class="hljs-subst">#{ivar}</span> = 0, <span class="hljs-subst">#{lvar}</span> = <span class="hljs-subst">#{svar}</span>.length&quot;</span>
        declareDown = <span class="hljs-string">&quot;<span class="hljs-subst">#{kvarAssign}</span><span class="hljs-subst">#{ivar}</span> = <span class="hljs-subst">#{svar}</span>.length - 1&quot;</span>
        compare = <span class="hljs-string">&quot;<span class="hljs-subst">#{ivar}</span> &lt; <span class="hljs-subst">#{lvar}</span>&quot;</span>
        compareDown = <span class="hljs-string">&quot;<span class="hljs-subst">#{ivar}</span> &gt;= 0&quot;</span>
        <span class="hljs-keyword">if</span> @step
          <span class="hljs-keyword">if</span> stepNum?
            <span class="hljs-keyword">if</span> down
              compare = compareDown
              declare = declareDown
          <span class="hljs-keyword">else</span>
            compare = <span class="hljs-string">&quot;<span class="hljs-subst">#{stepVar}</span> &gt; 0 ? <span class="hljs-subst">#{compare}</span> : <span class="hljs-subst">#{compareDown}</span>&quot;</span>
            declare = <span class="hljs-string">&quot;(<span class="hljs-subst">#{stepVar}</span> &gt; 0 ? (<span class="hljs-subst">#{declare}</span>) : <span class="hljs-subst">#{declareDown}</span>)&quot;</span>
          increment = <span class="hljs-string">&quot;<span class="hljs-subst">#{ivar}</span> += <span class="hljs-subst">#{stepVar}</span>&quot;</span>
        <span class="hljs-keyword">else</span>
          increment = <span class="hljs-string">&quot;<span class="hljs-subst">#{<span class="hljs-keyword">if</span> kvar <span class="hljs-keyword">isnt</span> ivar <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;++<span class="hljs-subst">#{ivar}</span>&quot;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;<span class="hljs-subst">#{ivar}</span>++&quot;</span>}</span>&quot;</span>
        forPartFragments = [@makeCode(<span class="hljs-string">&quot;<span class="hljs-subst">#{declare}</span>; <span class="hljs-subst">#{compare}</span>; <span class="hljs-subst">#{kvarAssign}</span><span class="hljs-subst">#{increment}</span>&quot;</span>)]
    <span class="hljs-keyword">if</span> @returns
      resultPart   = <span class="hljs-string">&quot;<span class="hljs-subst">#{@tab}</span><span class="hljs-subst">#{rvar}</span> = [];\n&quot;</span>
      returnResult = <span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>return <span class="hljs-subst">#{rvar}</span>;&quot;</span>
      body.makeReturn rvar
    <span class="hljs-keyword">if</span> @guard
      <span class="hljs-keyword">if</span> body.expressions.length &gt; <span class="hljs-number">1</span>
        body.expressions.unshift <span class="hljs-keyword">new</span> If (<span class="hljs-keyword">new</span> Parens @guard).invert(), <span class="hljs-keyword">new</span> StatementLiteral <span class="hljs-string">&quot;continue&quot;</span>
      <span class="hljs-keyword">else</span>
        body = Block.wrap [<span class="hljs-keyword">new</span> If @guard, body] <span class="hljs-keyword">if</span> @guard
    <span class="hljs-keyword">if</span> @pattern
      body.expressions.unshift <span class="hljs-keyword">new</span> Assign @name, <span class="hljs-keyword">if</span> @from <span class="hljs-keyword">then</span> <span class="hljs-keyword">new</span> IdentifierLiteral kvar <span class="hljs-keyword">else</span> <span class="hljs-keyword">new</span> Literal <span class="hljs-string">&quot;<span class="hljs-subst">#{svar}</span>[<span class="hljs-subst">#{kvar}</span>]&quot;</span>

    varPart = <span class="hljs-string">&quot;\n<span class="hljs-subst">#{idt1}</span><span class="hljs-subst">#{namePart}</span>;&quot;</span> <span class="hljs-keyword">if</span> namePart
    <span class="hljs-keyword">if</span> @object
      forPartFragments = [@makeCode(<span class="hljs-string">&quot;<span class="hljs-subst">#{kvar}</span> in <span class="hljs-subst">#{svar}</span>&quot;</span>)]
      guardPart = <span class="hljs-string">&quot;\n<span class="hljs-subst">#{idt1}</span>if (!<span class="hljs-subst">#{utility <span class="hljs-string">&#x27;hasProp&#x27;</span>, o}</span>.call(<span class="hljs-subst">#{svar}</span>, <span class="hljs-subst">#{kvar}</span>)) continue;&quot;</span> <span class="hljs-keyword">if</span> @own
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @from
      <span class="hljs-keyword">if</span> @await
        forPartFragments = <span class="hljs-keyword">new</span> Op <span class="hljs-string">&#x27;await&#x27;</span>, <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Literal <span class="hljs-string">&quot;<span class="hljs-subst">#{kvar}</span> of <span class="hljs-subst">#{svar}</span>&quot;</span>
        forPartFragments = forPartFragments.compileToFragments o, LEVEL_TOP
      <span class="hljs-keyword">else</span>
        forPartFragments = [@makeCode(<span class="hljs-string">&quot;<span class="hljs-subst">#{kvar}</span> of <span class="hljs-subst">#{svar}</span>&quot;</span>)]
    bodyFragments = body.compileToFragments merge(o, indent: idt1), LEVEL_TOP
    <span class="hljs-keyword">if</span> bodyFragments <span class="hljs-keyword">and</span> bodyFragments.length &gt; <span class="hljs-number">0</span>
      bodyFragments = [].concat @makeCode(<span class="hljs-string">&#x27;\n&#x27;</span>), bodyFragments, @makeCode(<span class="hljs-string">&#x27;\n&#x27;</span>)

    fragments = [@makeCode(defPart)]
    fragments.push @makeCode(resultPart) <span class="hljs-keyword">if</span> resultPart
    forCode = <span class="hljs-keyword">if</span> @await <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;for &#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;for (&#x27;</span>
    forClose = <span class="hljs-keyword">if</span> @await <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;)&#x27;</span>
    fragments = fragments.concat @makeCode(@tab), @makeCode( forCode),
      forPartFragments, @makeCode(<span class="hljs-string">&quot;<span class="hljs-subst">#{forClose}</span> {<span class="hljs-subst">#{guardPart}</span><span class="hljs-subst">#{varPart}</span>&quot;</span>), bodyFragments,
      @makeCode(@tab), @makeCode(<span class="hljs-string">&#x27;}&#x27;</span>)
    fragments.push @makeCode(returnResult) <span class="hljs-keyword">if</span> returnResult
    fragments

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
<span class="hljs-function">    <span class="hljs-title">addToScope</span> = <span class="hljs-params">(name)</span> -&gt;</span>
      alreadyDeclared = o.scope.find name.value
      name.isDeclaration = <span class="hljs-keyword">not</span> alreadyDeclared
    @name?.eachName addToScope, checkAssignability: <span class="hljs-literal">no</span>
    @index?.eachName addToScope, checkAssignability: <span class="hljs-literal">no</span>
    super o

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;For&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      source: @source?.ast o
      body: @body.ast o, LEVEL_TOP
      guard: @guard?.ast(o) ? <span class="hljs-literal">null</span>
      name: @name?.ast(o) ? <span class="hljs-literal">null</span>
      index: @index?.ast(o) ? <span class="hljs-literal">null</span>
      step: @step?.ast(o) ? <span class="hljs-literal">null</span>
      postfix: !!@postfix
      own: !!@own
      await: !!@await
      style: <span class="hljs-keyword">switch</span>
        <span class="hljs-keyword">when</span> @from   <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;from&#x27;</span>
        <span class="hljs-keyword">when</span> @object <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;of&#x27;</span>
        <span class="hljs-keyword">when</span> @name   <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;in&#x27;</span>
        <span class="hljs-keyword">else</span>              <span class="hljs-string">&#x27;range&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-342">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-342">&#x00a7;</a>
              </div>
              <h3 id="switch">Switch</h3>

            </div>
            
        </li>
        
        
        <li id="section-343">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-343">&#x00a7;</a>
              </div>
              <p>A JavaScript <em>switch</em> statement. Converts into a returnable expression on-demand.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Switch = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Switch</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@subject, @cases, @otherwise)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;subject&#x27;</span>, <span class="hljs-string">&#x27;cases&#x27;</span>, <span class="hljs-string">&#x27;otherwise&#x27;</span>]

  isStatement: YES

  jumps: <span class="hljs-function"><span class="hljs-params">(o = {block: <span class="hljs-literal">yes</span>})</span> -&gt;</span>
    <span class="hljs-keyword">for</span> {block} <span class="hljs-keyword">in</span> @cases
      <span class="hljs-keyword">return</span> jumpNode <span class="hljs-keyword">if</span> jumpNode = block.jumps o
    @otherwise?.jumps o

  makeReturn: <span class="hljs-function"><span class="hljs-params">(results, mark)</span> -&gt;</span>
    block.makeReturn(results, mark) <span class="hljs-keyword">for</span> {block} <span class="hljs-keyword">in</span> @cases
    @otherwise <span class="hljs-keyword">or</span>= <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Literal <span class="hljs-string">&#x27;void 0&#x27;</span>] <span class="hljs-keyword">if</span> results
    @otherwise?.makeReturn results, mark
    this

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    idt1 = o.indent + TAB
    idt2 = o.indent = idt1 + TAB
    fragments = [].concat @makeCode(@tab + <span class="hljs-string">&quot;switch (&quot;</span>),
      (<span class="hljs-keyword">if</span> @subject <span class="hljs-keyword">then</span> @subject.compileToFragments(o, LEVEL_PAREN) <span class="hljs-keyword">else</span> @makeCode <span class="hljs-string">&quot;false&quot;</span>),
      @makeCode(<span class="hljs-string">&quot;) {\n&quot;</span>)
    <span class="hljs-keyword">for</span> {conditions, block}, i <span class="hljs-keyword">in</span> @cases
      <span class="hljs-keyword">for</span> cond <span class="hljs-keyword">in</span> flatten [conditions]
        cond  = cond.invert() <span class="hljs-keyword">unless</span> @subject
        fragments = fragments.concat @makeCode(idt1 + <span class="hljs-string">&quot;case &quot;</span>), cond.compileToFragments(o, LEVEL_PAREN), @makeCode(<span class="hljs-string">&quot;:\n&quot;</span>)
      fragments = fragments.concat body, @makeCode(<span class="hljs-string">&#x27;\n&#x27;</span>) <span class="hljs-keyword">if</span> (body = block.compileToFragments o, LEVEL_TOP).length &gt; <span class="hljs-number">0</span>
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">if</span> i <span class="hljs-keyword">is</span> @cases.length - <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @otherwise
      expr = @lastNode block.expressions
      <span class="hljs-keyword">continue</span> <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">instanceof</span> Return <span class="hljs-keyword">or</span> expr <span class="hljs-keyword">instanceof</span> Throw <span class="hljs-keyword">or</span> (expr <span class="hljs-keyword">instanceof</span> Literal <span class="hljs-keyword">and</span> expr.jumps() <span class="hljs-keyword">and</span> expr.value <span class="hljs-keyword">isnt</span> <span class="hljs-string">&#x27;debugger&#x27;</span>)
      fragments.push cond.makeCode(idt2 + <span class="hljs-string">&#x27;break;\n&#x27;</span>)
    <span class="hljs-keyword">if</span> @otherwise <span class="hljs-keyword">and</span> @otherwise.expressions.length
      fragments.push @makeCode(idt1 + <span class="hljs-string">&quot;default:\n&quot;</span>), (@otherwise.compileToFragments o, LEVEL_TOP)..., @makeCode(<span class="hljs-string">&quot;\n&quot;</span>)
    fragments.push @makeCode @tab + <span class="hljs-string">&#x27;}&#x27;</span>
    fragments

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;SwitchStatement&#x27;</span>

  casesAst: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    cases = []

    <span class="hljs-keyword">for</span> kase, caseIndex <span class="hljs-keyword">in</span> @cases
      {conditions: tests, block: consequent} = kase
      tests = flatten [tests]
      lastTestIndex = tests.length - <span class="hljs-number">1</span>
      <span class="hljs-keyword">for</span> test, testIndex <span class="hljs-keyword">in</span> tests
        testConsequent =
          <span class="hljs-keyword">if</span> testIndex <span class="hljs-keyword">is</span> lastTestIndex
            consequent
          <span class="hljs-keyword">else</span>
            <span class="hljs-literal">null</span>

        caseLocationData = test.locationData
        caseLocationData = mergeLocationData caseLocationData, testConsequent.expressions[testConsequent.expressions.length - <span class="hljs-number">1</span>].locationData <span class="hljs-keyword">if</span> testConsequent?.expressions.length
        caseLocationData = mergeLocationData caseLocationData, kase.locationData, justLeading: <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> testIndex <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
        caseLocationData = mergeLocationData caseLocationData, kase.locationData, justEnding:  <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> testIndex <span class="hljs-keyword">is</span> lastTestIndex

        cases.push <span class="hljs-keyword">new</span> SwitchCase(test, testConsequent, trailing: testIndex <span class="hljs-keyword">is</span> lastTestIndex).withLocationDataFrom locationData: caseLocationData

    <span class="hljs-keyword">if</span> @otherwise?.expressions.length
      cases.push <span class="hljs-keyword">new</span> SwitchCase(<span class="hljs-literal">null</span>, @otherwise).withLocationDataFrom @otherwise

    kase.ast(o) <span class="hljs-keyword">for</span> kase <span class="hljs-keyword">in</span> cases

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      discriminant: @subject?.ast(o, LEVEL_PAREN) ? <span class="hljs-literal">null</span>
      cases: @casesAst o

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SwitchCase</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@test, @block, {@trailing} = {})</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;test&#x27;</span>, <span class="hljs-string">&#x27;block&#x27;</span>]

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      test: @test?.ast(o, LEVEL_PAREN) ? <span class="hljs-literal">null</span>
      consequent: @block?.ast(o, LEVEL_TOP).body ? []
      trailing: !!@trailing

<span class="hljs-built_in">exports</span>.SwitchWhen = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SwitchWhen</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@conditions, @block)</span> -&gt;</span>
    super()

  children: [<span class="hljs-string">&#x27;conditions&#x27;</span>, <span class="hljs-string">&#x27;block&#x27;</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-344">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-344">&#x00a7;</a>
              </div>
              <h3 id="if">If</h3>

            </div>
            
        </li>
        
        
        <li id="section-345">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-345">&#x00a7;</a>
              </div>
              <p><em>If/else</em> statements. Acts as an expression by pushing down requested returns
to the last line of each clause.</p>
<p>Single-expression <strong>Ifs</strong> are compiled into conditional operators if possible,
because ternaries are already proper expressions, and don’t need conversion.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.If = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">If</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  constructor: <span class="hljs-function"><span class="hljs-params">(@condition, @body, options = {})</span> -&gt;</span>
    super()
    @elseBody  = <span class="hljs-literal">null</span>
    @isChain   = <span class="hljs-literal">false</span>
    {@soak, @postfix, @type} = options
    moveComments @condition, @ <span class="hljs-keyword">if</span> @condition.comments

  children: [<span class="hljs-string">&#x27;condition&#x27;</span>, <span class="hljs-string">&#x27;body&#x27;</span>, <span class="hljs-string">&#x27;elseBody&#x27;</span>]

  bodyNode:     <span class="hljs-function">-&gt;</span> @body?.unwrap()
  elseBodyNode: <span class="hljs-function">-&gt;</span> @elseBody?.unwrap()</pre></div></div>
            
        </li>
        
        
        <li id="section-346">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-346">&#x00a7;</a>
              </div>
              <p>Rewrite a chain of <strong>Ifs</strong> to add a default case as the final <em>else</em>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  addElse: <span class="hljs-function"><span class="hljs-params">(elseBody)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @isChain
      @elseBodyNode().addElse elseBody
      @locationData = mergeLocationData @locationData, @elseBodyNode().locationData
    <span class="hljs-keyword">else</span>
      @isChain  = elseBody <span class="hljs-keyword">instanceof</span> If
      @elseBody = @ensureBlock elseBody
      @elseBody.updateLocationDataIfMissing elseBody.locationData
      @locationData = mergeLocationData @locationData, @elseBody.locationData <span class="hljs-keyword">if</span> @locationData? <span class="hljs-keyword">and</span> @elseBody.locationData?
    this</pre></div></div>
            
        </li>
        
        
        <li id="section-347">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-347">&#x00a7;</a>
              </div>
              <p>The <strong>If</strong> only compiles into a statement if either of its bodies needs
to be a statement. Otherwise a conditional operator is safe.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  isStatement: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o?.level <span class="hljs-keyword">is</span> LEVEL_TOP <span class="hljs-keyword">or</span>
      @bodyNode().isStatement(o) <span class="hljs-keyword">or</span> @elseBodyNode()?.isStatement(o)

  jumps: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> @body.jumps(o) <span class="hljs-keyword">or</span> @elseBody?.jumps(o)

  compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @isStatement o <span class="hljs-keyword">then</span> @compileStatement o <span class="hljs-keyword">else</span> @compileExpression o

  makeReturn: <span class="hljs-function"><span class="hljs-params">(results, mark)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> mark
      @body?.makeReturn results, mark
      @elseBody?.makeReturn results, mark
      <span class="hljs-keyword">return</span>
    @elseBody  <span class="hljs-keyword">or</span>= <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Literal <span class="hljs-string">&#x27;void 0&#x27;</span>] <span class="hljs-keyword">if</span> results
    @body     <span class="hljs-keyword">and</span>= <span class="hljs-keyword">new</span> Block [@body.makeReturn results]
    @elseBody <span class="hljs-keyword">and</span>= <span class="hljs-keyword">new</span> Block [@elseBody.makeReturn results]
    this

  ensureBlock: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Block <span class="hljs-keyword">then</span> node <span class="hljs-keyword">else</span> <span class="hljs-keyword">new</span> Block [node]</pre></div></div>
            
        </li>
        
        
        <li id="section-348">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-348">&#x00a7;</a>
              </div>
              <p>Compile the <code>If</code> as a regular <em>if-else</em> statement. Flattened chains
force inner <em>else</em> bodies into statement form.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileStatement: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    child    = del o, <span class="hljs-string">&#x27;chainChild&#x27;</span>
    exeq     = del o, <span class="hljs-string">&#x27;isExistentialEquals&#x27;</span>

    <span class="hljs-keyword">if</span> exeq
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> If(@processedCondition().invert(), @elseBodyNode(), type: <span class="hljs-string">&#x27;if&#x27;</span>).compileToFragments o

    indent   = o.indent + TAB
    cond     = @processedCondition().compileToFragments o, LEVEL_PAREN
    body     = @ensureBlock(@body).compileToFragments merge o, {indent}
    ifPart   = [].concat @makeCode(<span class="hljs-string">&quot;if (&quot;</span>), cond, @makeCode(<span class="hljs-string">&quot;) {\n&quot;</span>), body, @makeCode(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>}&quot;</span>)
    ifPart.unshift @makeCode @tab <span class="hljs-keyword">unless</span> child
    <span class="hljs-keyword">return</span> ifPart <span class="hljs-keyword">unless</span> @elseBody
    answer = ifPart.concat @makeCode(<span class="hljs-string">&#x27; else &#x27;</span>)
    <span class="hljs-keyword">if</span> @isChain
      o.chainChild = <span class="hljs-literal">yes</span>
      answer = answer.concat @elseBody.unwrap().compileToFragments o, LEVEL_TOP
    <span class="hljs-keyword">else</span>
      answer = answer.concat @makeCode(<span class="hljs-string">&quot;{\n&quot;</span>), @elseBody.compileToFragments(merge(o, {indent}), LEVEL_TOP), @makeCode(<span class="hljs-string">&quot;\n<span class="hljs-subst">#{@tab}</span>}&quot;</span>)
    answer</pre></div></div>
            
        </li>
        
        
        <li id="section-349">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-349">&#x00a7;</a>
              </div>
              <p>Compile the <code>If</code> as a conditional operator.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  compileExpression: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    cond = @processedCondition().compileToFragments o, LEVEL_COND
    body = @bodyNode().compileToFragments o, LEVEL_LIST
    alt  = <span class="hljs-keyword">if</span> @elseBodyNode() <span class="hljs-keyword">then</span> @elseBodyNode().compileToFragments(o, LEVEL_LIST) <span class="hljs-keyword">else</span> [@makeCode(<span class="hljs-string">&#x27;void 0&#x27;</span>)]
    fragments = cond.concat @makeCode(<span class="hljs-string">&quot; ? &quot;</span>), body, @makeCode(<span class="hljs-string">&quot; : &quot;</span>), alt
    <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_COND <span class="hljs-keyword">then</span> @wrapInParentheses fragments <span class="hljs-keyword">else</span> fragments

  unfoldSoak: <span class="hljs-function">-&gt;</span>
    @soak <span class="hljs-keyword">and</span> this

  processedCondition: <span class="hljs-function">-&gt;</span>
    @processedConditionCache ?= <span class="hljs-keyword">if</span> @type <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;unless&#x27;</span> <span class="hljs-keyword">then</span> @condition.invert() <span class="hljs-keyword">else</span> @condition

  isStatementAst: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.level <span class="hljs-keyword">is</span> LEVEL_TOP

  astType: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> @isStatementAst o
      <span class="hljs-string">&#x27;IfStatement&#x27;</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">&#x27;ConditionalExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    isStatement = @isStatementAst o

    <span class="hljs-keyword">return</span>
      test: @condition.ast o, <span class="hljs-keyword">if</span> isStatement <span class="hljs-keyword">then</span> LEVEL_PAREN <span class="hljs-keyword">else</span> LEVEL_COND
      consequent:
        <span class="hljs-keyword">if</span> isStatement
          @body.ast o, LEVEL_TOP
        <span class="hljs-keyword">else</span>
          @bodyNode().ast o, LEVEL_TOP
      alternate:
        <span class="hljs-keyword">if</span> @isChain
          @elseBody.unwrap().ast o, <span class="hljs-keyword">if</span> isStatement <span class="hljs-keyword">then</span> LEVEL_TOP <span class="hljs-keyword">else</span> LEVEL_COND
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> isStatement <span class="hljs-keyword">and</span> @elseBody?.expressions?.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
          @elseBody.expressions[<span class="hljs-number">0</span>].ast o, LEVEL_TOP
        <span class="hljs-keyword">else</span>
          @elseBody?.ast(o, LEVEL_TOP) ? <span class="hljs-literal">null</span>
      postfix: !!@postfix
      inverted: @type <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;unless&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-350">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-350">&#x00a7;</a>
              </div>
              <p>A sequence expression e.g. <code>(a; b)</code>.
Currently only used during AST generation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Sequence = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Sequence</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  children: [<span class="hljs-string">&#x27;expressions&#x27;</span>]

  constructor: <span class="hljs-function"><span class="hljs-params">(@expressions)</span> -&gt;</span>
    super()

  astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> @expressions[<span class="hljs-number">0</span>].ast(o) <span class="hljs-keyword">if</span> @expressions.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
    super o

  astType: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;SequenceExpression&#x27;</span>

  astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span>
      expressions:
        expression.ast(o) <span class="hljs-keyword">for</span> expression <span class="hljs-keyword">in</span> @expressions</pre></div></div>
            
        </li>
        
        
        <li id="section-351">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-351">&#x00a7;</a>
              </div>
              <h2 id="constants">Constants</h2>

            </div>
            
        </li>
        
        
        <li id="section-352">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-352">&#x00a7;</a>
              </div>
              
            </div>
            
            <div class="content"><div class='highlight'><pre>
UTILITIES =
  modulo: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;function(a, b) { return (+a % (b = +b) + b) % b; }&#x27;</span>

  boundMethodCheck: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&quot;
    function(instance, Constructor) {
      if (!(instance instanceof Constructor)) {
        throw new Error(&#x27;Bound instance method accessed before binding&#x27;);
      }
    }
  &quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-353">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-353">&#x00a7;</a>
              </div>
              <p>Shortcuts to speed up the lookup time for native functions.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  hasProp: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;{}.hasOwnProperty&#x27;</span>
  indexOf: <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;[].indexOf&#x27;</span>
  slice  : <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;[].slice&#x27;</span>
  splice : <span class="hljs-function">-&gt;</span> <span class="hljs-string">&#x27;[].splice&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-354">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-354">&#x00a7;</a>
              </div>
              <p>Levels indicate a node’s position in the AST. Useful for knowing if
parens are necessary or superfluous.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>LEVEL_TOP    = <span class="hljs-number">1</span>  <span class="hljs-comment"># ...;</span>
LEVEL_PAREN  = <span class="hljs-number">2</span>  <span class="hljs-comment"># (...)</span>
LEVEL_LIST   = <span class="hljs-number">3</span>  <span class="hljs-comment"># [...]</span>
LEVEL_COND   = <span class="hljs-number">4</span>  <span class="hljs-comment"># ... ? x : y</span>
LEVEL_OP     = <span class="hljs-number">5</span>  <span class="hljs-comment"># !...</span>
LEVEL_ACCESS = <span class="hljs-number">6</span>  <span class="hljs-comment"># ...[0]</span></pre></div></div>
            
        </li>
        
        
        <li id="section-355">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-355">&#x00a7;</a>
              </div>
              <p>Tabs are two spaces for pretty printing.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>TAB = <span class="hljs-string">&#x27;  &#x27;</span>

SIMPLENUM = <span class="hljs-regexp">/^[+-]?\d+(?:_\d+)*$/</span>
SIMPLE_STRING_OMIT = <span class="hljs-regexp">/\s*\n\s*/g</span>
LEADING_BLANK_LINE  = <span class="hljs-regexp">/^[^\n\S]*\n/</span>
TRAILING_BLANK_LINE = <span class="hljs-regexp">/\n[^\n\S]*$/</span>
STRING_OMIT    = <span class="hljs-regexp">///
    ((?:\\\\)+)      <span class="hljs-comment"># Consume (and preserve) an even number of backslashes.</span>
  | \\[^\S\n]*\n\s*  <span class="hljs-comment"># Remove escaped newlines.</span>
///</span>g
HEREGEX_OMIT = <span class="hljs-regexp">///
    ((?:\\\\)+)     <span class="hljs-comment"># Consume (and preserve) an even number of backslashes.</span>
  | \\(\s)          <span class="hljs-comment"># Preserve escaped whitespace.</span>
  | \s+(?:<span class="hljs-comment">#.*)?     # Remove whitespace and comments.</span>
///</span>g</pre></div></div>
            
        </li>
        
        
        <li id="section-356">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-356">&#x00a7;</a>
              </div>
              <h2 id="helper-functions">Helper Functions</h2>

            </div>
            
        </li>
        
        
        <li id="section-357">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-357">&#x00a7;</a>
              </div>
              
            </div>
            
        </li>
        
        
        <li id="section-358">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-358">&#x00a7;</a>
              </div>
              <p>Helper for ensuring that utility functions are assigned at the top level.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">utility</span> = <span class="hljs-params">(name, o)</span> -&gt;</span>
  {root} = o.scope
  <span class="hljs-keyword">if</span> name <span class="hljs-keyword">of</span> root.utilities
    root.utilities[name]
  <span class="hljs-keyword">else</span>
    ref = root.freeVariable name
    root.assign ref, UTILITIES[name] o
    root.utilities[name] = ref
<span class="hljs-function">
<span class="hljs-title">multident</span> = <span class="hljs-params">(code, tab, includingFirstLine = <span class="hljs-literal">yes</span>)</span> -&gt;</span>
  endsWithNewLine = code[code.length - <span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;\n&#x27;</span>
  code = (<span class="hljs-keyword">if</span> includingFirstLine <span class="hljs-keyword">then</span> tab <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>) + code.replace <span class="hljs-regexp">/\n/g</span>, <span class="hljs-string">&quot;$&amp;<span class="hljs-subst">#{tab}</span>&quot;</span>
  code = code.replace <span class="hljs-regexp">/\s+$/</span>, <span class="hljs-string">&#x27;&#x27;</span>
  code = code + <span class="hljs-string">&#x27;\n&#x27;</span> <span class="hljs-keyword">if</span> endsWithNewLine
  code</pre></div></div>
            
        </li>
        
        
        <li id="section-359">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-359">&#x00a7;</a>
              </div>
              <p>Wherever in CoffeeScript 1 we might’ve inserted a <code>makeCode &quot;#{@tab}&quot;</code> to
indent a line of code, now we must account for the possibility of comments
preceding that line of code. If there are such comments, indent each line of
such comments, and <em>then</em> indent the first following line of code.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">indentInitial</span> = <span class="hljs-params">(fragments, node)</span> -&gt;</span>
  <span class="hljs-keyword">for</span> fragment, fragmentIndex <span class="hljs-keyword">in</span> fragments
    <span class="hljs-keyword">if</span> fragment.isHereComment
      fragment.code = multident fragment.code, node.tab
    <span class="hljs-keyword">else</span>
      fragments.splice fragmentIndex, <span class="hljs-number">0</span>, node.makeCode <span class="hljs-string">&quot;<span class="hljs-subst">#{node.tab}</span>&quot;</span>
      <span class="hljs-keyword">break</span>
  fragments
<span class="hljs-function">
<span class="hljs-title">hasLineComments</span> = <span class="hljs-params">(node)</span> -&gt;</span>
  <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> node.comments
  <span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> node.comments
    <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> comment.here <span class="hljs-keyword">is</span> <span class="hljs-literal">no</span>
  <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-360">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-360">&#x00a7;</a>
              </div>
              <p>Move the <code>comments</code> property from one object to another, deleting it from
the first object.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">moveComments</span> = <span class="hljs-params">(<span class="hljs-keyword">from</span>, to)</span> -&gt;</span>
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> <span class="hljs-keyword">from</span>?.comments
  attachCommentsToNode <span class="hljs-keyword">from</span>.comments, to
  <span class="hljs-keyword">delete</span> <span class="hljs-keyword">from</span>.comments</pre></div></div>
            
        </li>
        
        
        <li id="section-361">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-361">&#x00a7;</a>
              </div>
              <p>Sometimes when compiling a node, we want to insert a fragment at the start
of an array of fragments; but if the start has one or more comment fragments,
we want to insert this fragment after those but before any non-comments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">unshiftAfterComments</span> = <span class="hljs-params">(fragments, fragmentToInsert)</span> -&gt;</span>
  inserted = <span class="hljs-literal">no</span>
  <span class="hljs-keyword">for</span> fragment, fragmentIndex <span class="hljs-keyword">in</span> fragments <span class="hljs-keyword">when</span> <span class="hljs-keyword">not</span> fragment.isComment
    fragments.splice fragmentIndex, <span class="hljs-number">0</span>, fragmentToInsert
    inserted = <span class="hljs-literal">yes</span>
    <span class="hljs-keyword">break</span>
  fragments.push fragmentToInsert <span class="hljs-keyword">unless</span> inserted
  fragments
<span class="hljs-function">
<span class="hljs-title">isLiteralArguments</span> = <span class="hljs-params">(node)</span> -&gt;</span>
  node <span class="hljs-keyword">instanceof</span> IdentifierLiteral <span class="hljs-keyword">and</span> node.value <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;arguments&#x27;</span>
<span class="hljs-function">
<span class="hljs-title">isLiteralThis</span> = <span class="hljs-params">(node)</span> -&gt;</span>
  node <span class="hljs-keyword">instanceof</span> ThisLiteral <span class="hljs-keyword">or</span> (node <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">and</span> node.bound)
<span class="hljs-function">
<span class="hljs-title">shouldCacheOrIsAssignable</span> = <span class="hljs-params">(node)</span> -&gt;</span> node.shouldCache() <span class="hljs-keyword">or</span> node.isAssignable?()</pre></div></div>
            
        </li>
        
        
        <li id="section-362">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-362">&#x00a7;</a>
              </div>
              <p>Unfold a node’s child if soak, then tuck the node under created <code>If</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">unfoldSoak</span> = <span class="hljs-params">(o, parent, name)</span> -&gt;</span>
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> ifn = parent[name].unfoldSoak o
  parent[name] = ifn.body
  ifn.body = <span class="hljs-keyword">new</span> Value parent
  ifn</pre></div></div>
            
        </li>
        
        
        <li id="section-363">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-363">&#x00a7;</a>
              </div>
              <p>Constructs a string or regex by escaping certain characters.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">makeDelimitedLiteral</span> = <span class="hljs-params">(body, {delimiter: delimiterOption, escapeNewlines, double, includeDelimiters = <span class="hljs-literal">yes</span>, escapeDelimiter = <span class="hljs-literal">yes</span>, convertTrailingNullEscapes} = {})</span> -&gt;</span>
  body = <span class="hljs-string">&#x27;(?:)&#x27;</span> <span class="hljs-keyword">if</span> body <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;&#x27;</span> <span class="hljs-keyword">and</span> delimiterOption <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;/&#x27;</span>
  escapeTemplateLiteralCurlies = delimiterOption <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;`&#x27;</span>
  regex = <span class="hljs-regexp">///
      (\\\\)                               <span class="hljs-comment"># Escaped backslash.</span>
    | (\\0(?=\d))                          <span class="hljs-comment"># Null character mistaken as octal escape.</span>
    <span class="hljs-subst">#{
      <span class="hljs-keyword">if</span> convertTrailingNullEscapes
        <span class="hljs-regexp">/// | (\\0) $ ///</span>.source           # Trailing <span class="hljs-literal">null</span> character that could be mistaken <span class="hljs-keyword">as</span> octal <span class="hljs-built_in">escape</span>.
      <span class="hljs-keyword">else</span>
        <span class="hljs-string">&#x27;&#x27;</span>
    }</span>
    <span class="hljs-subst">#{
      <span class="hljs-keyword">if</span> escapeDelimiter
        <span class="hljs-regexp">/// | \\?(<span class="hljs-subst">#{delimiterOption}</span>) ///</span>.source # (Possibly escaped) delimiter.
      <span class="hljs-keyword">else</span>
        <span class="hljs-string">&#x27;&#x27;</span>
    }</span>
    <span class="hljs-subst">#{
      <span class="hljs-keyword">if</span> escapeTemplateLiteralCurlies
        <span class="hljs-regexp">/// | \\?(\$\{) ///</span>.source         # `<span class="language-javascript">${</span>` inside template literals must be escaped.
      <span class="hljs-keyword">else</span>
        <span class="hljs-string">&#x27;&#x27;</span>
    }</span>
    | \\?(?:
        <span class="hljs-subst">#{<span class="hljs-keyword">if</span> escapeNewlines <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;(\n)|&#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>}</span>
          (\r)
        | (\u2028)
        | (\u2029)
      )                                    <span class="hljs-comment"># (Possibly escaped) newlines.</span>
    | (\\.)                                <span class="hljs-comment"># Other escapes.</span>
  ///</span>g
  body = body.replace regex, <span class="hljs-function"><span class="hljs-params">(match, backslash, nul, ...args)</span> -&gt;</span>
    trailingNullEscape =
      args.shift() <span class="hljs-keyword">if</span> convertTrailingNullEscapes
    delimiter =
      args.shift() <span class="hljs-keyword">if</span> escapeDelimiter
    templateLiteralCurly =
      args.shift() <span class="hljs-keyword">if</span> escapeTemplateLiteralCurlies
    lf =
      args.shift() <span class="hljs-keyword">if</span> escapeNewlines
    [cr, ls, ps, other] = args
    <span class="hljs-keyword">switch</span></pre></div></div>
            
        </li>
        
        
        <li id="section-364">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-364">&#x00a7;</a>
              </div>
              <p>Ignore escaped backslashes.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">when</span> backslash <span class="hljs-keyword">then</span> (<span class="hljs-keyword">if</span> double <span class="hljs-keyword">then</span> backslash + backslash <span class="hljs-keyword">else</span> backslash)
      <span class="hljs-keyword">when</span> nul                  <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;\\x00&#x27;</span>
      <span class="hljs-keyword">when</span> trailingNullEscape   <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;\\x00&quot;</span>
      <span class="hljs-keyword">when</span> delimiter            <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;\\<span class="hljs-subst">#{delimiter}</span>&quot;</span>
      <span class="hljs-keyword">when</span> templateLiteralCurly <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;\\${&quot;</span>
      <span class="hljs-keyword">when</span> lf                   <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;\\n&#x27;</span>
      <span class="hljs-keyword">when</span> cr                   <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;\\r&#x27;</span>
      <span class="hljs-keyword">when</span> ls                   <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;\\u2028&#x27;</span>
      <span class="hljs-keyword">when</span> ps                   <span class="hljs-keyword">then</span> <span class="hljs-string">&#x27;\\u2029&#x27;</span>
      <span class="hljs-keyword">when</span> other                <span class="hljs-keyword">then</span> (<span class="hljs-keyword">if</span> double <span class="hljs-keyword">then</span> <span class="hljs-string">&quot;\\<span class="hljs-subst">#{other}</span>&quot;</span> <span class="hljs-keyword">else</span> other)
  printedDelimiter = <span class="hljs-keyword">if</span> includeDelimiters <span class="hljs-keyword">then</span> delimiterOption <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>
  <span class="hljs-string">&quot;<span class="hljs-subst">#{printedDelimiter}</span><span class="hljs-subst">#{body}</span><span class="hljs-subst">#{printedDelimiter}</span>&quot;</span>
<span class="hljs-function">
<span class="hljs-title">sniffDirectives</span> = <span class="hljs-params">(expressions, {notFinalExpression} = {})</span> -&gt;</span>
  index = <span class="hljs-number">0</span>
  lastIndex = expressions.length - <span class="hljs-number">1</span>
  <span class="hljs-keyword">while</span> index &lt;= lastIndex
    <span class="hljs-keyword">break</span> <span class="hljs-keyword">if</span> index <span class="hljs-keyword">is</span> lastIndex <span class="hljs-keyword">and</span> notFinalExpression
    expression = expressions[index]
    <span class="hljs-keyword">if</span> (unwrapped = expression?.unwrap?()) <span class="hljs-keyword">instanceof</span> PassthroughLiteral <span class="hljs-keyword">and</span> unwrapped.generated
      index++
      <span class="hljs-keyword">continue</span>
    <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> expression <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> expression.isString() <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> expression.unwrap().shouldGenerateTemplateLiteral()
    expressions[index] =
      <span class="hljs-keyword">new</span> Directive expression
      .withLocationDataFrom expression
    index++
<span class="hljs-function">
<span class="hljs-title">astAsBlockIfNeeded</span> = <span class="hljs-params">(node, o)</span> -&gt;</span>
  unwrapped = node.unwrap()
  <span class="hljs-keyword">if</span> unwrapped <span class="hljs-keyword">instanceof</span> Block <span class="hljs-keyword">and</span> unwrapped.expressions.length &gt; <span class="hljs-number">1</span>
    unwrapped.makeReturn <span class="hljs-literal">null</span>, <span class="hljs-literal">yes</span>
    unwrapped.ast o, LEVEL_TOP
  <span class="hljs-keyword">else</span>
    node.ast o, LEVEL_PAREN</pre></div></div>
            
        </li>
        
        
        <li id="section-365">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-365">&#x00a7;</a>
              </div>
              <p>Helpers for <code>mergeLocationData</code> and <code>mergeAstLocationData</code> below.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">lesser</span>  = <span class="hljs-params">(a, b)</span> -&gt;</span> <span class="hljs-keyword">if</span> a &lt; b <span class="hljs-keyword">then</span> a <span class="hljs-keyword">else</span> b
<span class="hljs-function"><span class="hljs-title">greater</span> = <span class="hljs-params">(a, b)</span> -&gt;</span> <span class="hljs-keyword">if</span> a &gt; b <span class="hljs-keyword">then</span> a <span class="hljs-keyword">else</span> b
<span class="hljs-function">
<span class="hljs-title">isAstLocGreater</span> = <span class="hljs-params">(a, b)</span> -&gt;</span>
  <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> a.line &gt; b.line
  <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> a.line <span class="hljs-keyword">is</span> b.line
  a.column &gt; b.column
<span class="hljs-function">
<span class="hljs-title">isLocationDataStartGreater</span> = <span class="hljs-params">(a, b)</span> -&gt;</span>
  <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> a.first_line &gt; b.first_line
  <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> a.first_line <span class="hljs-keyword">is</span> b.first_line
  a.first_column &gt; b.first_column
<span class="hljs-function">
<span class="hljs-title">isLocationDataEndGreater</span> = <span class="hljs-params">(a, b)</span> -&gt;</span>
  <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> a.last_line &gt; b.last_line
  <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> a.last_line <span class="hljs-keyword">is</span> b.last_line
  a.last_column &gt; b.last_column</pre></div></div>
            
        </li>
        
        
        <li id="section-366">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-366">&#x00a7;</a>
              </div>
              <p>Take two nodes’ location data and return a new <code>locationData</code> object that
encompasses the location data of both nodes. So the new <code>first_line</code> value
will be the earlier of the two nodes’ <code>first_line</code> values, the new
<code>last_column</code> the later of the two nodes’ <code>last_column</code> values, etc.</p>
<p>If you only want to extend the first node’s location data with the start or
end location data of the second node, pass the <code>justLeading</code> or <code>justEnding</code>
options. So e.g. if <code>first</code>’s range is [4, 5] and <code>second</code>’s range is [1, 10],
you’d get:</p>
<pre><code>mergeLocationData(first, second).range                   <span class="hljs-comment"># [1, 10]</span>
mergeLocationData(first, second, justLeading: <span class="hljs-literal">yes</span>).range <span class="hljs-comment"># [1, 5]</span>
mergeLocationData(first, second, justEnding:  <span class="hljs-literal">yes</span>).range <span class="hljs-comment"># [4, 10]</span>
</code></pre>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.mergeLocationData = mergeLocationData = <span class="hljs-function"><span class="hljs-params">(locationDataA, locationDataB, {justLeading, justEnding} = {})</span> -&gt;</span>
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.assign(
    <span class="hljs-keyword">if</span> justEnding
      first_line:   locationDataA.first_line
      first_column: locationDataA.first_column
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">if</span> isLocationDataStartGreater locationDataA, locationDataB
        first_line:   locationDataB.first_line
        first_column: locationDataB.first_column
      <span class="hljs-keyword">else</span>
        first_line:   locationDataA.first_line
        first_column: locationDataA.first_column
  ,
    <span class="hljs-keyword">if</span> justLeading
      last_line:             locationDataA.last_line
      last_column:           locationDataA.last_column
      last_line_exclusive:   locationDataA.last_line_exclusive
      last_column_exclusive: locationDataA.last_column_exclusive
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">if</span> isLocationDataEndGreater locationDataA, locationDataB
        last_line:             locationDataA.last_line
        last_column:           locationDataA.last_column
        last_line_exclusive:   locationDataA.last_line_exclusive
        last_column_exclusive: locationDataA.last_column_exclusive
      <span class="hljs-keyword">else</span>
        last_line:             locationDataB.last_line
        last_column:           locationDataB.last_column
        last_line_exclusive:   locationDataB.last_line_exclusive
        last_column_exclusive: locationDataB.last_column_exclusive
  ,
    range: [
      <span class="hljs-keyword">if</span> justEnding
        locationDataA.range[<span class="hljs-number">0</span>]
      <span class="hljs-keyword">else</span>
        lesser locationDataA.range[<span class="hljs-number">0</span>], locationDataB.range[<span class="hljs-number">0</span>]
    ,
      <span class="hljs-keyword">if</span> justLeading
        locationDataA.range[<span class="hljs-number">1</span>]
      <span class="hljs-keyword">else</span>
        greater locationDataA.range[<span class="hljs-number">1</span>], locationDataB.range[<span class="hljs-number">1</span>]
    ]
  )</pre></div></div>
            
        </li>
        
        
        <li id="section-367">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-367">&#x00a7;</a>
              </div>
              <p>Take two AST nodes, or two AST nodes’ location data objects, and return a new
location data object that encompasses the location data of both nodes. So the
new <code>start</code> value will be the earlier of the two nodes’ <code>start</code> values, the
new <code>end</code> value will be the later of the two nodes’ <code>end</code> values, etc.</p>
<p>If you only want to extend the first node’s location data with the start or
end location data of the second node, pass the <code>justLeading</code> or <code>justEnding</code>
options. So e.g. if <code>first</code>’s range is [4, 5] and <code>second</code>’s range is [1, 10],
you’d get:</p>
<pre><code>mergeAstLocationData(first, second).range                   <span class="hljs-comment"># [1, 10]</span>
mergeAstLocationData(first, second, justLeading: <span class="hljs-literal">yes</span>).range <span class="hljs-comment"># [1, 5]</span>
mergeAstLocationData(first, second, justEnding:  <span class="hljs-literal">yes</span>).range <span class="hljs-comment"># [4, 10]</span>
</code></pre>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.mergeAstLocationData = mergeAstLocationData = <span class="hljs-function"><span class="hljs-params">(nodeA, nodeB, {justLeading, justEnding} = {})</span> -&gt;</span>
  <span class="hljs-keyword">return</span>
    loc:
      start:
        <span class="hljs-keyword">if</span> justEnding
          nodeA.loc.start
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">if</span> isAstLocGreater nodeA.loc.start, nodeB.loc.start
            nodeB.loc.start
          <span class="hljs-keyword">else</span>
            nodeA.loc.start
      end:
        <span class="hljs-keyword">if</span> justLeading
          nodeA.loc.end
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">if</span> isAstLocGreater nodeA.loc.end, nodeB.loc.end
            nodeA.loc.end
          <span class="hljs-keyword">else</span>
            nodeB.loc.end
    range: [
      <span class="hljs-keyword">if</span> justEnding
        nodeA.range[<span class="hljs-number">0</span>]
      <span class="hljs-keyword">else</span>
        lesser nodeA.range[<span class="hljs-number">0</span>], nodeB.range[<span class="hljs-number">0</span>]
    ,
      <span class="hljs-keyword">if</span> justLeading
        nodeA.range[<span class="hljs-number">1</span>]
      <span class="hljs-keyword">else</span>
        greater nodeA.range[<span class="hljs-number">1</span>], nodeB.range[<span class="hljs-number">1</span>]
    ]
    start:
      <span class="hljs-keyword">if</span> justEnding
        nodeA.start
      <span class="hljs-keyword">else</span>
        lesser nodeA.start, nodeB.start
    end:
      <span class="hljs-keyword">if</span> justLeading
        nodeA.end
      <span class="hljs-keyword">else</span>
        greater nodeA.end, nodeB.end</pre></div></div>
            
        </li>
        
        
        <li id="section-368">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-368">&#x00a7;</a>
              </div>
              <p>Convert Jison-style node class location data to Babel-style location data</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.jisonLocationDataToAstLocationData = jisonLocationDataToAstLocationData = <span class="hljs-function"><span class="hljs-params">({first_line, first_column, last_line_exclusive, last_column_exclusive, range})</span> -&gt;</span>
  <span class="hljs-keyword">return</span>
    loc:
      start:
        line:   first_line + <span class="hljs-number">1</span>
        column: first_column
      end:
        line:   last_line_exclusive + <span class="hljs-number">1</span>
        column: last_column_exclusive
    range: [
      range[<span class="hljs-number">0</span>]
      range[<span class="hljs-number">1</span>]
    ]
    start: range[<span class="hljs-number">0</span>]
    end:   range[<span class="hljs-number">1</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-369">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-369">&#x00a7;</a>
              </div>
              <p>Generate a zero-width location data that corresponds to the end of another node’s location.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">zeroWidthLocationDataFromEndLocation</span> = <span class="hljs-params">({range: [, endRange], last_line_exclusive, last_column_exclusive})</span> -&gt;</span> {
  first_line: last_line_exclusive
  first_column: last_column_exclusive
  last_line: last_line_exclusive
  last_column: last_column_exclusive
  last_line_exclusive
  last_column_exclusive
  range: [endRange, endRange]
}
<span class="hljs-function">
<span class="hljs-title">extractSameLineLocationDataFirst</span> = <span class="hljs-params">(numChars)</span> -&gt;</span> ({range: [startRange], first_line, first_column}) -&gt; {
  first_line
  first_column
  last_line: first_line
  last_column: first_column + numChars - <span class="hljs-number">1</span>
  last_line_exclusive: first_line
  last_column_exclusive: first_column + numChars
  range: [startRange, startRange + numChars]
}
<span class="hljs-function">
<span class="hljs-title">extractSameLineLocationDataLast</span> = <span class="hljs-params">(numChars)</span> -&gt;</span> ({range: [, endRange], last_line, last_column, last_line_exclusive, last_column_exclusive}) -&gt; {
  first_line: last_line
  first_column: last_column - (numChars - <span class="hljs-number">1</span>)
  last_line: last_line
  last_column: last_column
  last_line_exclusive
  last_column_exclusive
  range: [endRange - numChars, endRange]
}</pre></div></div>
            
        </li>
        
        
        <li id="section-370">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-370">&#x00a7;</a>
              </div>
              <p>We don’t currently have a token corresponding to the empty space
between interpolation/JSX expression braces, so piece together the location
data by trimming the braces from the Interpolation’s location data.
Technically the last_line/last_column calculation here could be
incorrect if the ending brace is preceded by a newline, but
last_line/last_column aren’t used for AST generation anyway.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">emptyExpressionLocationData</span> = <span class="hljs-params">({interpolationNode: element, openingBrace, closingBrace})</span> -&gt;</span>
  first_line:            element.locationData.first_line
  first_column:          element.locationData.first_column + openingBrace.length
  last_line:             element.locationData.last_line
  last_column:           element.locationData.last_column - closingBrace.length
  last_line_exclusive:   element.locationData.last_line
  last_column_exclusive: element.locationData.last_column
  range: [
    element.locationData.range[<span class="hljs-number">0</span>] + openingBrace.length
    element.locationData.range[<span class="hljs-number">1</span>] - closingBrace.length
  ]</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>
